Unfortunately there's no way to use a Lisp as a GC-less systems language. The syntax is tied to the evaluation model, which depends on being able to perform arbitrary allocations in the construction of a value. Even if you implemented a new dialect designed for manual memory management, there would simply be no way around this problem.
The goofy syntax is not even the worst problem with C, by far. It's the way it straddles the huge gulf between "portable assembler" and "fast applications language" and isn't especially good at either of those roles. A language trying to replace C should aim for one side of that chasm or the other, and do a better job there.
There are some inconsistencies with the syntax; however, the syntax itself is simple and (for the most part) consistent.
Name:
Anonymous2014-12-03 14:01
>>22 Also ugly and stupid. Why does the return type come before the function name? Why do I have to visually fish the line to get the fucking name of what's being declared?
>>22 Another thing that's wrong with C's syntax is that the "pointer" operator at the type level is the same as the "dereference pointer" at the value level. Because of that I always want to throw up when I see C code. These are two fucking opposite operations, who had the idea to denote them with the same (*) sign? Fucking idiots.
Name:
Anonymous2014-12-03 14:20
Also the array syntax is stupid. Why is it int arr[] if it's not an int? It's an array of ints, the [] needs to go to the type, ya incestuous drunken faggots. Hey, it's equivalent to int* arr (at least in function arguments), so why does the * go to the type if the [] goes to the identifier? Fucking disgusting.
>>27 The return type before the function type is the least of the concerns about its syntax,
Name:
Anonymous2014-12-03 15:11
>>28 Well why don't you tell us your major concerns about its syntax? Also if it's a small concern, why was this mistake fixed in newer languages like Rust and Go?
Name:
Anonymous2014-12-03 15:40
>>28 Having the return type anywhere else is stupid and doesn't make any sense.
>>23-25,31 You do not understand C. Naturally you are frustrated and confused by what you do not understand. But, as I know better, I will selflessly go out of my way to enlighten you.
In other languages, you would write the identifier, and then the identifier's type: Foo : Integer, Bar : Map<String, Float>, and word []char. But the syntax for declaring such identifiers is completely different from the syntax for using them in your code, which complicates the language: You must be able to express both the name of the type itself and the way it is used.
In C, there is a different basic rule: You write the type of an expression (the contents of a dereferenced pointer or array, or the return value of a function) and then you write an expression invoking the identifier you are declaring, using exactly the same syntax as you would in normal code. And naturally, the type of that expression is the same type that precedes it in the declaration: The type of *p is int, and therefore you would write int *p. The type of buf[n] is unsigned char, and therefore you would write unsigned char buf[BUFSIZ].
If it were not done this way, C would need additional syntax for each of these types: A special syntax for function types, a special syntax for pointer types, and so on. Reusing what is already there allows the compiler to save precious memory and grammar complexity by simplifying the language. It is the best choice a language designer could have made.
>>33 Okay, I see some sort of rationale behind C's syntax, but it still doesn't justify the choices made for C. For example, writing the function declaration like
int func_name(...);
would make sense in a pure language, where the expression func_name(...) may indeed be replaced by a value of type int. But it doesn't make sense in C because there are unrestricted implicit side effects everywhere, and a function call is not, as a rule, observationally equivalent to its return value.
Same goes for the other arguments:
1) C wouldn't need a special syntax for function types because it doesn't have function types. It forces you to use (void *) for all function types.
2) C already has special syntax for pointer types, e.g.
[code]typedef int* IntPtr ;
3) C already has an infernally complex grammar. If simplicity was wanted, why not use s-exps? They're much simpler.
1) C wouldn't need a special syntax for function types because it doesn't have function types. It forces you to use (void *) for all function types.
Wait, what?
typedef int* IntPtr
It's not special syntax.
If simplicity was wanted, why not use s-exps?
Because it would look like shit for C.
Name:
Anonymous2014-12-03 19:02
Okay, OP, here you go. Here's what C might look like with a different syntax and basically no other changes (except fallthrough because fuck that)
function main(argc: Int, argv: [[Char]]) -> Int do var ch: Int var stdout_lock: FileLock setlocale(LC_TYPE, "") while (ch = getopt(argc, argv, "belnstuv")) != 1 do case ch of 'b' => bflag = nflag = 1 'e' => eflag = vflag = 1 'l' => lflag = 1 'n' => nflag = 1 else usage() end case end while argv += optind if lflag then stdout_lock.l_len = 0 stdout_lock.l_start = 0 stdout_lock.l_type = F_WRLCK stdout_lock.l_whence = SEEK_SET if fcntl(STDOUT_FILENO, F_SETLKW, addr_of stdout_lock) == -1 then err(EXIT_FAILURE, "stdout") end if end if
if bflag oror eflag oror nflag oror sflag oror tflag oror vflag then scanfiles(argv, 1) else scanfiles(argv, 0) end if
>>42 There's a good reason we don't write C like that: The English-style keywords are slower and use more memory than punctuation. Maybe you should stick to talking about dynamic languages where that kind of performance hit is deemed acceptable.
Name:
Anonymous2014-12-04 3:05
>>49 I think that English keywords to delimit structural blocks is as stupid as anyone else, but is performance really the way to make that argument? The difference between the resources used by each parser itself should be, like, nothing, compared to later compilation phases, and even less if you avoid the yacc/lex bloat.
Name:
Anonymous2014-12-04 6:56
>>49 No they don't. C is a compiled language, there are no English-style keywords in compiled C code.
As discussed above, covariant arrays leads to problem with writes into the array. Java and C# deals with this by marking each array object with a type when it is created. Each time a value is stored into an array, the compiler inserts a check that the run-time type of the value is equal to the run-time type of the array. If there is a mismatch, an ArrayStoreException (or ArrayTypeMismatchException in C#) is thrown:
Runtime checks have no place in C.
Name:
Anonymous2014-12-05 10:42
>>71 No, it is subtyping that is highly imperfect. Not generics.
Name:
Anonymous2014-12-05 10:46
No, it is subtyping that is highly imperfect and requires runtime tag checks all the time.
is what I meant.
Name:
Anonymous2014-12-05 10:51
>>72 Wow, you're right. I'm sorry. Please use a term that doesn't remind me of java in the future. But still, although clean generics that don't break with no inheritance could be done in C, you end up messing around with casting so much it isn't that big of a deal to have a data structure consisting of a single type of values and to always cast when you access them. You can't take types too seriously in C. There's too much freedom.
Name:
Anonymous2014-12-05 10:57
>>74 So you're saying that C is like a Lisp without GC then, OK. Greenspun's tenth rule QED.
>>75 I would say that lisp is an assembly language. Its core is simply and expressive, yet you can build things of near infinite complexity on top of it. C is the same way, except built upon a differnt assembly language. A real one instead of the lambda calculus. Also, much harder to build skyscrapers in.
Generic programming pioneer Alexander Stepanov wrote: "Generic programming is about abstracting and classifying algorithms and data structures. It gets its inspiration from Knuth and not from type theory. Its goal is the incremental construction of systematic catalogs of useful, efficient and abstract algorithms and data structures. Such an undertaking is still a dream."
Name:
Anonymous2014-12-05 21:28
javascript is C with a nicer syntax also look at asmjs.org
Name:
Anonymous2014-12-05 22:29
>>79 Since Java became popular. I would say expose yourself to industry, but you will eventually. You'll hate it. And then you'll kill yourself.
>>86 Go is not close to C despite being advertised as so.
Name:
Anonymous2014-12-06 1:01
>>84 That's harder than it sounds. What do you do with closed-over stack space when it's been returned from its owning function, or sent to another thread?
Why does the return type come before the function name?
To match the variable declaration syntax. int x; means "this is a variable that stores a variable of type int". int factorial() { ... } means "this is a function that generates a variable of type int". If you just think of functions as a dynamic counterpart to variables, it makes sense.