Hacker Newsnew | past | comments | ask | show | jobs | submit | nox_'s commentslogin

Cf. `try` becoming a keyword, when there are hundreds of calls to a method named `try` in Servo, one of the largest Rust projects in existence.


However, none of that affects a crate until it opts into the new syntax. So everything keeps building just fine.


The inflate crate is absolutely devoid of tests and full of unsafe code though, so the foundations of all of that are quite weak.


I implemented them in R17. José doesn't dislike them but doesn't have a syntax that fits Elixir for them, given parens around arguments of a lambda are optional.


I have rarely read things that were that much wrong. Just because the code can be represented as a data structure, or just because the compiler is written in its own language, that doesn't make a language homoiconic.


I concur -> In computer programming, homoiconicity (from the Greek words homo meaning the same and icon meaning representation) is a property of some programming languages in which the program structure is similar to its syntax, and therefore the program's internal representation can be inferred by reading the text's layout. Wiki


Every language's syntax internal representation can be inferred by reading it's text layout. It's what parsers do and people can, too.

How "similar" internal representation needs to be to its textual version to be homoiconic is subjective.

In Erlang an expression:

    2+3.
yields this AST:

    {op,1,'+',{integer,1,2},{integer,1,3}}
You can strip line and type annotations (you could also easily add them to the Prolog example below), which will get you:

    {'+', 2, 3}
If you scroll down the Wiki page you cite, you'll see an example in Prolog, where this:

    X is 2*5
yields AST of this shape:

    is(_, *(2, 5))
The important similarity here is that all elements of ASTs are still first class objects in the language. You can manipulate them in their raw form with the same functions you'd use for manipulating any other data. In other words, once you have an AST, you don't need to evaluate it, it's enough to just read it.

This is not true for Python. An expression:

    2+3
yields:

    Expression(body=BinOp(left=Num(n=2), op=Add(), right=Num(n=3)))
An AST here cannot be manipulated in its raw form here. To manipulate it - the representation itself - you'd have to parse it again or evaluate it to use special methods on AST objects.

So this is the practical definition of homoiconicity I came up with. You are of course free to disagree. I'm stressing "practical" here, because what I'm interested in is how easy it is to manipulate the AST to write macros. Homoiconicity for the sake of homoiconicity is of no interest to me.

PS. BTW, maybe I should base my argument on Lisp instead of Prolog. If you read the Wikipedia page carefully you'll see the part on Lisp says the same thing I do above.


Homoiconicity specifically means that the primary representation of the language is a datatype in the language itself; Erlang isn't that.

I don't find it particularly subjective, it's just what it means. According to what you're saying any language that can be parsed and manipulated by the language is homoiconic, since the AST can be represented by types available in the language, no?


> Homoiconicity specifically means that the primary representation of the language is a datatype in the language itself; Erlang isn't that.

Literal datatype.

And please, prove it to me that "Erlang isn't that". My examples above indicate quite clearly that yes, it is.

> I don't find it particularly subjective,

I was referring to the word "similar" which appeared in the definition of homoiconicity given by flackjap.

> since the AST can be represented by types available in the language, no?

Yes, if the datatypes used in AST representation have literal forms in the language. No otherwise.


You claim any language that can represent its AST using that language's literal datatypes is homoiconic?! No. I can represent an AST in array literals in essentially any language, and quite a few using object/hash notation. That alone does not make a language homoiconic. See, for example, the lengthy thread here: http://c2.com/cgi/wiki?HomoiconicExampleInJava


There's another constraint, as seen in the definition of homoiconicity from Wikipedia. I'll paste it once again:

> In computer programming, homoiconicity [...] is a property of some programming languages in which the program structure is similar to its syntax, and therefore the program's internal representation can be inferred by reading the text's layout. If a language is homoiconic, it means that the language text has the same structure as its abstract syntax tree (i.e. the AST and the syntax are isomorphic). This allows all code in the language to be accessed and transformed as data, using the same representation.

As I noted, a similarity is subjective, but I never claimed that it's not needed as a criterion. So, what I claim is that homoiconicity happens when the AST representation consists of only literal datatypes of the language AND the AST structure is "similar" to the original code.

That's it. And also:

> I can represent an AST in array literals in essentially any language

I doubt it, but that's irrelevant. Had you done it you'd essentially reimplement the language of your choice and then we're not talking about that language in general anymore, but about your implementation. What you say here is that "every language can be made homoiconic given appropriate AST implementation". And that's probably true, although I suspect it gets too hard to do in practice for more complex syntaxes.

May I ask where are you getting your strong convictions about homoiconicity from? If you read the Wiki page you'll notice the use of less than precise words, like "similar" or "Languages which are considered homoiconic include" and so on. The concept itself is not as clear-cut as you seem to believe and it's mostly defined by examples.

Also, you still didn't provide a convincing argument that Erlang is not homoiconic; you only claimed that "it isn't" and moved on.

EDIT: as an example of how subjective homoiconicity is take a look at Julia. Listed on the wikipedia as homoiconic, here are the details: http://docs.julialang.org/en/latest/manual/metaprogramming/ - if Julia is homoiconic, then Erlang and Elixir are too. And Haxe, and Dylan. Are they? I don't know, I'm not going to argue about this. As I said, homoiconicity is only interesting as a way of simplifying macro creation; any more discussion is honestly useless to me.


Erlang is not homoiconic. Did you mean Elixir? Neither are anyway.


Homoiconicity extends well beyond the obvious AST primacy of Lisp. Tcl and Io are homoiconic languages too, for example. The reason I used that word is because the Erlang language and libraries exploit a few basic data types (tuples and lists being composed into proplists and iolists) very well, to the point that a lot of practical Erlang code is simply shuffling data by pattern matching on those types. It's not a Lisp-level code-data correspondence, but it's in a similar league.


It really isn't homoiconicity if you can't compile an AST with it.

What you're describing are just simple data structures. Erlang has no user-definable data structures. I don't recall anything I've read explicitly stating this, but I've believed for a while that this was the case because it made moving terms across the network simpler. Thus, libraries aren't "exploiting" a few basic data types... they're stuck with a few basic data types. There's no alternative.

That really has nothing to do with 'homoiconicity'. Erlang code is not a data structure, and it is not spelled in Erlang terms. And that would generally not be a good thing! Erlang's already plenty verbose without also having to be expressed as legal Erlang data terms.

(The generally loosy-goosy typing that results is one of the reasons I don't like Erlang and am moving away from it. But YMMV.)


In which universe is polymorphism the opposite of isomorphism? Couldn't we just have said "JavaScript that runs everywhere" instead of trying to sound educated?


When you want to refer to the same concept over and over, it helps to give it a name.

Other examples: ajax, lamp, nosql, soa ... they may be buzzwords, but they are helpful. I don't see the problem here.


Isomorphism was already a word before Nodejitsu abused it. Your examples are acronyms and abbreviations.

Nevermind that this concept is not even worth a name.


It is common to repurpose words this way. I think it is called 'metaphor'. See also: half the names in technology and all nearly every apple product name.

Anyway, I find the term useful.


Metaphors make sense, that reusing of isomorphism doesn't, however you quote Greek words to justify your means.


Replying with an attack and closing comments is definitely something a douchebag would do. Free or opensource doesn't mean you get to be irresponsible about what you release or maintain, if your project has some caveats they should be listed explicitly.


Actually, it does-- have you ever even READ the MIT license?

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


When two languages have different scoping rules, they don't have the same semantics. When two languages differ in their opinion about macros, they don't have the same semantics.

When two languages have different semantics, they are different languages.

And finally, when two languages have fundamentally different syntaxes, the idioms promoted by their creators differ, and thus problems are solved in different ways.

They are not fundamentally the same language, no.


Erlang and Elixir aren't the same language, but they do share a pretty unique architecture in OTP. When people talk about "the advantages of Erlang" they're frequently really talking about OTP (that, or BEAM's reduction-counting ISA.) So people think it's Erlang that gives you those advantages.

Of course, it's not; any language that targets BEAM could pick up those advantages "for free", in the same way Clojure gets a bunch of Java libraries "for free." But people compare programming languages, not abstract machines or library ecosystems. If you treat Erlang and Elixir as black boxes, hiding BEAM and the OTP (the way someone who doesn't know either language would), then they seem to be much more similar to one-another than any other language is to either of them.


Sharing a common subset does not make them "fundamentally the same language".


>they seem to be much more similar to one-another than any other language is to either of them.


Scoping rules? I what way do they differ? Honest question.


Variables in Elixir can be rebound, and there are no unsafe variables at all in Elixir.


I wouldn't call it "scoping" difference, although I can see why one would think about it as such. It would be a real scoping issue if you could assign variables in outer scopes from inside the nested scopes. Can you?


You can. And even if you couldn't, what I mentioned is still different scoping rules, whether you put scare quotes or not.


> what I mentioned is still different scoping rules

You're probably right, I don't want to argue about terminology.

What do you mean by "scare quotes"? Honest question: English is my second language and I'm not very good with it.

> You can.

You're wrong. Here, take a look:

    iex(4)> f = fn() -> a = 0; (fn()->a=9 end).(); a end
    #Function<20.80484245/0 in :erl_eval.expr/5>
    iex(5)> f.()
    0
f.() should evaluate to 9 if what you said was true. Either there's a special syntax for doing this in Elixir (like nonlocal in Python 3) or it's absent, and then the scoping rules are the same in Elixir and Erlang, with a bit of syntactic sugar for SSA transformation, which you need to do by hand in Erlang.

Again, I'm not Elixir programmer, so this is a honest question: is there some special syntax which would make the example above produce 9? I doubt it very much because it wouldn't fit very well with BEAM, but everything is possible and I'd be glad to learn about another nice feature of Elixir.


You introduced a closure there. Bindings set in if, case, receive, etc will spill in their surrounding environment. Obviously they won't spill outside closures without mutable terms, which BEAM lacks.

The bits about SSA transformation needed to be done by hand in Erlang are a bit fun, because that's considered a feature in the Erlang realm.

The scoping rules aren't the same for the very reason you dismiss as an implementation detail.

Scare quotes: http://en.wikipedia.org/wiki/Scare_quotes


> The scoping rules aren't the same for the very reason you dismiss as an implementation detail.

Ok, this means that I need to learn some more about how scoping rules are defined and described, because apparently my current understanding is incompatible with the common one. That happens all the time if you're self-taught like me, so I simply accept this.

Thanks for discussion and the "scare quotes" term :)


"language"


Quotes don't magically let you say wrong things.


Hah, yeah, let's port everything for no obvious reason.


There actually are good, obvious reasons to prefer Elixir to Erlang. Syntax is actually significant to productivity. For one quick example, Erlang requires you to terminate statements with either a comma, or a period, depending on whether it's the last statement in the section. If you move code around, you need to go back at the end and fix the commas and periods. Typically, this happens in the form of an error message, which leads to a tedious extra step that happens to me maybe 15 times a day when working with Erlang. That problem doesn't exist in Elixir. There are quite a few other nice things too. Elixir increases productivity in real ways.


The syntax reason doesn't matter to existing Erlang developers -- you get used to the Erlang syntax, same as any other syntax.

The meta-programming on the other hand may well be a huge draw to Erlang shops.


Erlang and Elixir play very well together. I imagine Erlang shops "moving to Elixir" will be in the form of Erlang shops hiring people with Ruby experience and letting them use Elixir so they can get up to speed faster.


I knew Ruby pretty well before trying Erlang and used Erlang before trying Elixir -- I still find Erlang easier to write in that Elixir.

Elixir is more visually similar to Ruby, sure, buts its substantively not very similar, so the visual similarity is, if anything, a detriment, IMO.


Perhaps the problem is you used Erlang before trying Elixir.

For the typical programmer coming outside the Erlang/Elixir environment, Elixir is by far the more familiar and easier to pick up.


May be. It also may be that I have a lot less attachment to superficial syntactical similarity than lots of other people seem to -- I see lots of objections to languages not based on substance but based on the lack of familiar superficial structure, and that's not something that's really bothered me (one advantage, perhaps, of having learned -- even if only at a fairly superficial level in some cases -- several languages with radically different syntax in grade school), so "it superficially looks familiar" isn't bypassing, for me, a stumbling block lots of people seem to have.

In any case, yeah, I'm not saying that my personal Erlang vs. Elixir response is anything more than my personal response (or that Elixir isn't valuable; its certainly something I'd like to find time to explore more deeply and I think it has a lot to offer.)


Syntax is the least of your worries when learning a new language. Elixir isn't Ruby. Some new projects may be developed in Elixir but it will never supplant Erlang.


>Some new projects may be developed in Elixir but it will never supplant Erlang.

I vastly prefer Erlang syntax to Elixir's, but IMO it's way too early in the game to say this. In the unlikely event that the people who were attracted to Elixir because they couldn't handle Erlang's syntax can manage to grasp OTP, I imagine that Elixir would ultimately kill Erlang dead. An Erlang that has the same power and expressiveness, runs on the same VM, and is completely compatible - but looks like Algol - would be an irresistible force.


> - Elixir compiles directly to Erlang byte code

No, it compiles to Erlang. Which is then compiled by the Erlang compiler.


I guess I'm misinformed on this. The output of compiling Elixir files are .beam files, not .erl files. Maybe the Elixir compiler compiles to Erlang along the way?


Elixir's compiler emits Erlang forms, and then relies on OTP's Erlang's compiler. It is not a direct process.


Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: