Live data from Hacker News

Zinc: a low level language between assembler, C and C++ with Ruby-like syntax

tibleiz.net

31–40 of 51 posts

Re: Zinc: a low level language between assembler, C and C++ with Ruby-like syntax

#31
post #27

Earlier quoted context omitted.

A high-level language can turn a simple statement into arbitrarily-complicated run-time code, pretty much by definition. There are some high level languages where there is a pretty straightforward one-to-one correspondence of statement to bytecode(s). There isn't much syntax cross-talk to be had there. Explain the existence of Forth.

I said "run-time code", not bytecodes. I'm talking about what actually executes. I've seen "bytecodes" that qualify as high-level languages by this standard, like CPython bytecode. Is that even so surprising? Single bytecodes for OO languages can translate to a lot of work to resolve. And, what about Forth? It's a fairly low-level language by this standard. It has convenient ways to link together a lot of little func…

Actually, bytecodes for langs like Smalltalk can get you down to controlling all of your runtime state down to the level of bits. (Squeak actually runs bit-identical on something like 50 environments!)

As for precisely what runtime instructions are executed, most of the time, we can consider this to be an implementation detail. In the case of superscalar processors, you can't necessarily tell me what order your assembly language instructions are executed.

And, what about Forth? It's a fairly low-level language by this standard.

It bridges the gap between high-level and low level. It's a clear piece of evidence that there isn't such a huge gulf as you claim.

but one word does not dispatch on types and expand operator overloading and do the other things that can result in one line of C++ producing half a kilobyte of code

There are high level languages that don't do this either. Actually, I know of a specialized declarative Smalltalk that has gotten the entire image down to 45k. A Smalltalk VM is basically little more than a 256 branch switch statement, plus message dispatch, plus GC.

The gulf isn't nearly as large as you imagine. Rather, there are a number of "high level" languages that are actually pretty minimal.

Re: Zinc: a low level language between assembler, C and C++ with Ruby-like syntax

#32
post #27

Earlier quoted context omitted.

I said "run-time code", not bytecodes. I'm talking about what actually executes. I've seen "bytecodes" that qualify as high-level languages by this standard, like CPython bytecode. Is that even so surprising? Single bytecodes for OO languages can translate to a lot of work to resolve. And, what about Forth? It's a fairly low-level language by this standard. It has convenient ways to link together a lot of little func…

Actually, bytecodes for langs like Smalltalk can get you down to controlling all of your runtime state down to the level of bits. (Squeak actually runs bit-identical on something like 50 environments!) As for precisely what runtime instructions are executed, most of the time, we can consider this to be an implementation detail. In the case of superscalar processors, you can't necessarily tell me what order your assem…

You've really missed my point. I pretty much defined high level and low level by how they expanded out from simple instructions. You can't cite examples to prove this is wrong, by definition you've classified your definitions wrong. That this is not a universal definition doesn't bother me one little bit, because there is not universal definition of any non-trivial software engineering term.

Re: Zinc: a low level language between assembler, C and C++ with Ruby-like syntax

#33
post #22

Earlier quoted context omitted.

While i didn't panic, i find myself having quite a negative reaction to a language in which "Identifiers can have blanks" is listed under main features. EDIT : Also, i see quite the opportunity from wrong parsing, not on the machine side, but on the human side. blanks already have a function in other programming languages : They are here to separate symbols. By giving them this double meaning, you actually bring cont…

I don't see why parsing would be a problem; identifiers (and their pieces) always start with letters (so no "var 1"), alphanumerical, and cannot be a reserved word. Meaning, parse word by word until you hit a key word or a significant character (,:". etc). You can't have "varb function(arg)" or its equivalent in any language I know, because it doesn't make sense - there's no operation on the varb, it's just "there".…

Meaning, parse word by word until you hit a key word or a significant character (,:". etc).

If keywords are allowable in identifiers (such as "end of file"), then your algorithm is not sophisticated enough. When you encounter a token that is the same token as a keyword, you need to use context to determine if it is actually a keyword or part of an identifier.

This may be a serious problem if the grammar has " " in it. That is, "X keyword" could be the identifier "X keyword" or it could be the identifier "X" followed by "keyword." There's a reason that most programming languages require that identifiers are a single token.

Re: Zinc: a low level language between assembler, C and C++ with Ruby-like syntax

#34
I will try to ignore the shallow (but horrifying) issue of identifiers including spaces.

The real question to be asked here is what is wrong with the current portable assembler (C) ? C has occupied this niche for a long time and quite successfully - I believe all current mainstream kernels are written in C (or possibly a limited subset of C++).

If you want a 'portable assembler', a modern C compiler is in my opinion, a good choice:

  - a solid specification: detailing the behaviour of operations, what is defined, implementation, or undefined behaviour.

  - access to platform specific features through builtins and intrinsics

  - ability to use inline asm if you really want to (or need to)

  - easy integration with existing libraries

  - minimal dependencies on a runtime library (pretty much none in freestanding implementations)

  - most compliers give have ways to get good control of both what code is generated and structure layout.
The modern C ecosystem provides (mostly good) tools for:

  - tracking memory leaks/invalid memory accesses (valgrind)

  - static analysis (clang static analyser, sparse, coverity, ...)

  - debuggers (gdb ...)

  - solid optimizing compilers (icc, gcc, llvm)

  - profilers (oprofile, perf, vtune, ...)
Admittedly, most of these tools don't depend on the code being written in C, but I suspect any new language would take a while to get properly integrated. If you want to use a low level language, you really want to have access to these tools or equivalent.

A new language trying to compete in this space would have to offer something fairly substantial to get me to switch - and a strange syntax like zinc is not going to help. From the documentation at least, zinc seems to currently be missing: an equivalent to volatile; asm; anyway to access a CAS like instruction; 64bit types; floats; a way to interface to C code; clear documentation about behaviour in corner cases (what happens if you a left shift a 32bit value by 40?). The only thing seems to bring to the table to compensate is the ability to inherit structures

Re: Zinc: a low level language between assembler, C and C++ with Ruby-like syntax

#35
post #3

looks interesting but i cant get it to work on os x or linux.

Works for me. Here is how to do minimal 3-stage bootstrap.

  gcc bootstrap/io.c bootstrap/zc.c -o zc1
  ./zc1 -I lib -I lib/platform/default -I src src/main.zc -o zc2.c
  gcc lib/libc/io.c zc2.c -o zc2
  ./zc2 -I lib -I lib/platform/default -I src src/main.zc -o zc3.c
  cmp zc2.c zc3.c # should be identical

Re: Zinc: a low level language between assembler, C and C++ with Ruby-like syntax

#36
post #33
post #22

Earlier quoted context omitted.

I don't see why parsing would be a problem; identifiers (and their pieces) always start with letters (so no "var 1"), alphanumerical, and cannot be a reserved word. Meaning, parse word by word until you hit a key word or a significant character (,:". etc). You can't have "varb function(arg)" or its equivalent in any language I know, because it doesn't make sense - there's no operation on the varb, it's just "there".…

Meaning, parse word by word until you hit a key word or a significant character (,:". etc). If keywords are allowable in identifiers (such as "end of file"), then your algorithm is not sophisticated enough. When you encounter a token that is the same token as a keyword, you need to use context to determine if it is actually a keyword or part of an identifier. This may be a serious problem if the grammar has " " in it…

>If keywords are allowable in identifiers

Big "if" (why shouldn't it disallow them?), and completely resolved by modifying your naming scheme in those situations: EndOfFile is unambiguous, as is end_of_file, ifSuccess, etc.

Re: Zinc: a low level language between assembler, C and C++ with Ruby-like syntax

#37
post #36
post #33

Earlier quoted context omitted.

Meaning, parse word by word until you hit a key word or a significant character (,:". etc). If keywords are allowable in identifiers (such as "end of file"), then your algorithm is not sophisticated enough. When you encounter a token that is the same token as a keyword, you need to use context to determine if it is actually a keyword or part of an identifier. This may be a serious problem if the grammar has " " in it…

> If keywords are allowable in identifiers Big "if" (why shouldn't it disallow them?), and completely resolved by modifying your naming scheme in those situations: EndOfFile is unambiguous, as is end_of_file, ifSuccess, etc.

It's unusual as most programming languages allow keywords to appear in identifiers (for example, new_thing is a legal C++ identifier). Further, if I understand the language correctly, the literal "end_of_file" becomes the same identifier as "end of file". And the stated purpose of allowing white space in identifiers is to avoid camel case and underscores.

Re: Zinc: a low level language between assembler, C and C++ with Ruby-like syntax

#38
post #15

Earlier quoted context omitted.

>just-use-lisp-style-identifiers-then hitting - is not significantly easier than hitting _ when compared to hitting the spacebar. http://en.wikipedia.org/wiki/Fitts_law

This is yet another reason I enjoy typing in Dvorak :) (-_ is in a better place)

Haha! I'm on Dvorak too and didn't understand at all why JohnnyCache thought hitting "-" was so much harder than Space! I guess I've been completely converted for too long.

Re: Zinc: a low level language between assembler, C and C++ with Ruby-like syntax

#39
post #33
post #22

Earlier quoted context omitted.

I don't see why parsing would be a problem; identifiers (and their pieces) always start with letters (so no "var 1"), alphanumerical, and cannot be a reserved word. Meaning, parse word by word until you hit a key word or a significant character (,:". etc). You can't have "varb function(arg)" or its equivalent in any language I know, because it doesn't make sense - there's no operation on the varb, it's just "there".…

Meaning, parse word by word until you hit a key word or a significant character (,:". etc). If keywords are allowable in identifiers (such as "end of file"), then your algorithm is not sophisticated enough. When you encounter a token that is the same token as a keyword, you need to use context to determine if it is actually a keyword or part of an identifier. This may be a serious problem if the grammar has " " in it…

> When you encounter a token that is the same token as a keyword, you need to use context to determine if it is actually a keyword or part of an identifier.

You're presuming here that a space delimits tokens. In this language, that may not be the case. The lexer may create a single token from "a b c".

Re: Zinc: a low level language between assembler, C and C++ with Ruby-like syntax

#40

I will try to ignore the shallow (but horrifying) issue of identifiers including spaces. The real question to be asked here is what is wrong with the current portable assembler (C) ? C has occupied this niche for a long time and quite successfully - I believe all current mainstream kernels are written in C (or possibly a limited subset of C++). If you want a 'portable assembler', a modern C compiler is in my opinion,…

I agree with you. I just wanted to list the one complaint I do have about C: missed optimization opportunities due to lax aliasing rules.

Consider the following C translation unit:

    void foo(const int *i);
    void bar();

    int baz() {
      int i = 1;
      foo(&i);
      return i + 1;
    }

    int quux() {
      int i;
      foo(&i);
      i = 1;
      bar();
      return i + 1;
    }
You'd like to think that both baz() and quux() could compile the return statements to a constant "return 2." After all, foo() is taking a pointer to a CONST int. But alas, this is not the case, because foo() could cast away the const. So in truth, both functions are forced to reload the integer from the stack, add 1 to it, and then return that! You can't use any values you had loaded in registers (or in this case, you can't evaluate the expression at compile time).

My example is contrived, but you can easily construct examples that fit the same pattern and are real.

I've heard that Fortran still beats C in optimization in some cases; I would expect that the above is one major reason why. C99's "restrict" addresses some of the difference but cannot help you with the above.

Post reply on HN