HackerLangs
TopNewTrendsCommentsPastAskShowJobs

gf000

1,913 karmajoined 2 lata temu

comments

gf000
·13 godzin temu·discuss
Well, my main point is not to never use macros, but that in certain cases a language-native feature that can also solve a problem you would use a macro for, it's probably better (better debugging, error messages, etc).

And my other point was macro systems in other languages, which I believe are better, in part due to not having homoiconicity, like Scala or rust.
gf000
·16 godzin temu·discuss
Well, I was talking about the fundamental part. Of course you can have more practical implementations, like Scala or rust's macro system, that gives you a proper typed AST.
gf000
·16 godzin temu·discuss
I mentioned in other comment that homoiconicity doesn't necessarily make writing macros simpler. It makes writing trivial toy examples simpler.

But let's compare it to a modern macro system like rust's or scala's, where you get a typed object representation of the AST, and for anything non-trivial you are better off with this latter.

Also, arguably the best is to have certain features in the language itself, that can be used to build proper abstractions - so you don't have to resolve to using macros in its place.
gf000
·16 godzin temu·discuss
I would argue the functional bias when you have so much mutability.

Also, only the first one is remotely unique.
gf000
·17 godzin temu·discuss
Thank you for the reply, and I definitely agree with you on many points. I absolutely don't want to take away from Lisp that it is somehow uniquely elegant, and does have a mathematical beauty to it, this is certain.

I just feel this (and its practical ramifications) are often overexaggerated.
gf000
·20 godzin temu·discuss
My issue is that a language is just as much about what it disallows, as much as about what it allows.

It's absolutely trivial to allow everything, you just have to make a Turing-complete extension either by design or accidentally.

It's much much harder to carefully choose more limiting primitives that only allow you to build stuff that keep certain important properties about them. You can't subtract stuff after the fact.

E.g. something like rust's borrow checker could not be realistically implemented as "a lisp" macro (what does lisp even mean in this case). For that to work you would literally build a rust compiler over s-expressions and you might as well leave off the s-expressions at that point.

And every part that was not compiled by that macro or whatever would be unsafe and could not interact with the "rust-lisp" compiled parts, as you can no longer assert anything about them (there is nothing mandating the usual single writer, xor multiple read-only references laws)
gf000
·21 godzin temu·discuss
And that's just syntax, it doesn't give you a programming language at all.

JS is a dynamically typed language with prototypical inheritance objects that work like universal key-value maps for the most part. It is also mutable.

Clojure is a dynamically typed language with key-value maps. It is also immutable.

You can surely see where I'm going , the underlying semantic model is the meaningful part. Homoiconicity doesn't give you anything special if your language can parse itself and can eval code. It just makes these completely abstract implementations simpler.
gf000
·21 godzin temu·discuss
Well, if we have a compiler that sees a constant value, it can completely optimize out one branch. But it of course depends on the semantics of the language.

But yeah you are right in case of a naive compiler.
gf000
·21 godzin temu·discuss
Well, maybe because digital is better at showing small differences in this case? Like on a 50kmh road, dropping below 50 is quite noticeable in digital, less so with a line above or below another line.

But for the revs, I think it's quite clear that the analog is better.

Maybe one way to put it would be how important an exact value is? For the speed, it is. For revs, the relative value and its change is much more important and humans track movement much better.
gf000
·22 godziny temu·discuss
There are plenty of languages with macros though, nothing special about lisps.

And no, language semantics absolutely don't compose. Like you can't just do some kind of optimization in one place if you do some mutation on it in another place. Optimizations work on global assumptions that every part of the codebase have to abide by. Any part not doing it will make the whole thing crumble - and "there is no stuck in lisp" is exactly why you can't have your cake and eat it too.
gf000
·22 godziny temu·discuss
Well, compilers have layers - you ain't outputting assembly from the AST layer directly, usually there is some kind of IR. Like LLVM have plenty of layers.

And for a simple DSL you can usually just use a sufficiently expressive language, no need for macros. Like kotlin/Scala has html DSLs that look pretty decent.

For anything more complex though, you can't just "compose stuff", a type system is a global property so for that you literally have to write something way more complex than a local macro should contain.
gf000
·22 godziny temu·discuss
So then what it is? Because otherwise it's a magical nothing-term to which everything lisp people like applies, but no criticism can ever reach it because "that's not really lisp, see it's different in this other implementation"
gf000
·22 godziny temu·discuss
At the same time, you get a mushy tree as input, instead of a properly typed AST "object" with accessible "function name", "method parameters" everything that you can just refer to.

It will be the third arguments' 2nd arg with s-exprs, following your arbitrary pattern you figured you want to use. So it's very arguable which is easier to use, sure for some "party tricks" lisps will win, for anything more useful my vote would go with rust/Scala macros for sure. So again, you win nothing by homoiconicity, the by-the-compiler implemented parse function is more complex in rust, which is 100% abstracted away.
gf000
·22 godziny temu·discuss
Well, as mentioned that's why you create two lambdas as the branches. This is pretty much what thunks are in some languages (like Haskell), so this example doesn't strictly require macros per se.
gf000
·22 godziny temu·discuss
Can you expand on that? I am mildly experienced with Clojure, and much more so with the JVM and I see no reason for that to happen (besides perhaps some kind of module shenanigans or importing stuff that requires special flags?)
gf000
·22 godziny temu·discuss
Can you parse code into an in-memory representation and can you eval?

If yes, then you can do everything that Lisp repls can.

The parser being slightly more complex than parsing s-expressions doesn't materially change anything.
gf000
·22 godziny temu·discuss
Why do you think other people who have fallen in love with, say, Ruby, are less experienced in other languages? They just have less of a cult.
gf000
·22 godziny temu·discuss
What idea? S-expressions?

Because that's all these languages share. What's common in CL and Clojure? They are as dissimilar as C and Scala.
gf000
·22 godziny temu·discuss
If you squint enough, JS is a lisp..

Define a goddamn language, syntax is not enough to define one! What are the semantics? Without that you are just talking about syntax trees like they would mean anything
gf000
·22 godziny temu·discuss
I agree with you on overloading - the real word here should be "expressivity", which is defined by language constructs that could NOT be syntactic sugared into a local context. Those may occasionally be useful, though not by itself. E.g. gotos are more expressive by the above definition, yet it was largely deemed to not be a useful "power".