Earlier quoted context omitted.
It indeed isn't. Here's my litmus test. Is 2^100 always equal to 2^100? Let's ask SBCL: * (eq (expt 2 100) (expt 2 100)) NIL Damn object identities, ruining muh equalities. (Disclaimer: I'm not saying functional programming is the right approach for writing every program, but if a language can't even get arithmetic and relational operators right...)
Well, I would just use EQL. If you want to use Haskell, use Haskell. Common Lisp works differently.
Swift and the Legacy of Functional Programming
171–180 of 188 posts
Re: Swift and the Legacy of Functional Programming
#172Earlier quoted context omitted.
I'm aware of EQUALP. But the problem remains that it's possible to distinguish between supposedly “equal” values. Lisp and Scala are first and foremost object-oriented languages - whatever values you want to manipulate are always subordinate to objects whose physical identity in memory matters in the language's semantics, no matter how irrelevant they might be for your problem domain. On the other hand, in Haskell an…
I am also aware of that. I am not really trying to convince you of anything, mostly trying to prevent casual readers from being taught Common Lisp from you. Look at the example you just gave, this is beyond ridiculous. I would prefer if you were focusing on what you want to fight "for", not what you want to fight "against". You like having a strong separation between the language and its implementation. I get it. Not…
Those would be implementation details, not part of the language itself. Hence...
> There probably is an identity equality operator down there, that people cannot access.
... this doesn't make sense.
> You have access to internals, by choice, just as if you were writing Haskell ASTs using an Haskell compiler's internal API.
However, there's no way to portably manipulate compiler internals in Haskell. Heck, Haskell syntax, unlike Lisp syntax, can actually be represented in multiple ways: named variables, de Bruijn indices and levels, HOAS, etc. And this is a good thing.
> In all PL discussions, there is eventually mention of an hypothetical sufficiently smart compiler.
I wouldn't have brought it up myself.
> The CL point of view is (among other things) that such a compiler is one where a programmer can easily add its own extensions.
There's no dichotomy between extensibility and abstraction enforcement, even if you try to set up one.
Re: Swift and the Legacy of Functional Programming
#173Re: Swift and the Legacy of Functional Programming
#174Earlier quoted context omitted.
Excuse my ignorance but why is the first one parallelizable but not the second?
Maybe we aren't speaking the same language, but I never mentioned parallelism in my text. We could talk about why the first example could be parallelized of course, but that's not what I wanted to talk about and you missed the point ;-)
Re: Swift and the Legacy of Functional Programming
#175Earlier quoted context omitted.
This sounds pretty misinformed. There are plenty of choices in between Scala and Haskell; Clojure and Elixir are two other relatively popular languages that come to mind.
You might have fallen victim to misinformation yourself. In general, functional programming in Scala tends to be more FP, with code tending to be more pure than in Clojure and I have no experience with Elixir, but I have some experience with Erlang and FP code in Scala tends to be held at a higher standard than in Erlang. Of course, you've picked 2 dynamic languages as examples and FP in dynamic languages is differen…
You cannot get away with these things as easily in the Erlang VM (and thus Elixir). I agree with your assessment that Clojure with its macros is an ugly hack, and requires discipline to get right.
Having said that, Haskell also takes a lot of discipline to get right (no lazy I/O, for example), and allows you to get away with ugly things as well (unsafePerformIO). The type system makes it a lot easier to get right though (or in other words, more difficult to do the wrong thing).
Re: Swift and the Legacy of Functional Programming
#176Earlier quoted context omitted.
I am also aware of that. I am not really trying to convince you of anything, mostly trying to prevent casual readers from being taught Common Lisp from you. Look at the example you just gave, this is beyond ridiculous. I would prefer if you were focusing on what you want to fight "for", not what you want to fight "against". You like having a strong separation between the language and its implementation. I get it. Not…
> Note however that if you are the Haskell compiler, you can know things the programmer cannot, or you can inject code that can perform manipulations the programmer cannot express. Those would be implementation details, not part of the language itself. Hence... > There probably is an identity equality operator down there, that people cannot access. ... this doesn't make sense. > You have access to internals, by choic…
In order to have an ML, you take a subset of Common Lisp and specialize/extend it in a very specific direction. The part that are removed from Lisp are the one you don't care about. I care about being able to use different equivalence classes, including the ones the compiler is going to require, like identity equality, because this matters when I implement abstractions myself.
> However, there's no way to portably manipulate compiler internals in Haskell.
Yes, why not, that would be damn useful. The alternative is to hack each implementation in its own way.
> Heck, Haskell syntax, unlike Lisp syntax, can actually be represented in multiple ways: [...]
Do you get the difference between internal and external representations? When you see (lambda (a) (+ a 1)), you don't know how the code is represented internally and how its value, when executed, is represented internally (when my compiler performs data-flow analysis, it uses a specific internal representation I don't need to know). Yet, you have access to a uniform API, defined at the language level, to manipulate data. That's why you can have the same source code working on the JVM, interpreted using a C/C++ runtime or directly expressed as assembly. In that sense, there is a separation between the language and its implementation. But part of the language specification is also there to guarantee a uniform way of building new extensions and integrate them with the compiler. That is a good thing. What is not enforced is how and when each feature is used. If that matters, dump a specialized Lisp image that you call the "compiler" and call it with Make on a file expressed in your custom DSL.
> There's no dichotomy between extensibility and abstraction enforcement, even if you try to set up one.
I am not trying to set up one. Just read more carefully.
Re: Swift and the Legacy of Functional Programming
#177Earlier quoted context omitted.
> Note however that if you are the Haskell compiler, you can know things the programmer cannot, or you can inject code that can perform manipulations the programmer cannot express. Those would be implementation details, not part of the language itself. Hence... > There probably is an identity equality operator down there, that people cannot access. ... this doesn't make sense. > You have access to internals, by choic…
> ... this doesn't make sense. In order to have an ML, you take a subset of Common Lisp and specialize/extend it in a very specific direction. The part that are removed from Lisp are the one you don't care about. I care about being able to use different equivalence classes, including the ones the compiler is going to require, like identity equality, because this matters when I implement abstractions myself. > However…
I'm not talking about representations of semantic objects. I'm talking about representations of syntax. In Lisp's case, you don't get to choose - the macro system critically depends on a particular representation (named variables). Have fun writing macros that operate on HOAS.
Re: Swift and the Legacy of Functional Programming
#178Earlier quoted context omitted.
> ... this doesn't make sense. In order to have an ML, you take a subset of Common Lisp and specialize/extend it in a very specific direction. The part that are removed from Lisp are the one you don't care about. I care about being able to use different equivalence classes, including the ones the compiler is going to require, like identity equality, because this matters when I implement abstractions myself. > However…
> Do you get the difference between internal and external representations? When you see (lambda (a) (+ a 1)), you don't know how the code is represented internally and how its value, when executed [emphasis mine], is represented internally I'm not talking about representations of semantic objects. I'm talking about representations of syntax . In Lisp's case, you don't get to choose - the macro system critically depen…
Please tell me how Haskell represents HOAS and how this is not possible in Lisp.
Also, read Barzilay's paper (http://scheme2006.cs.uchicago.edu/15-barzilay.pdf), or about the Ergo Project (1988! http://repository.cmu.edu/cgi/viewcontent.cgi?article=2763&c...).
Re: Swift and the Legacy of Functional Programming
#179Earlier quoted context omitted.
> ... this doesn't make sense. In order to have an ML, you take a subset of Common Lisp and specialize/extend it in a very specific direction. The part that are removed from Lisp are the one you don't care about. I care about being able to use different equivalence classes, including the ones the compiler is going to require, like identity equality, because this matters when I implement abstractions myself. > However…
> Do you get the difference between internal and external representations? When you see (lambda (a) (+ a 1)), you don't know how the code is represented internally and how its value, when executed [emphasis mine], is represented internally I'm not talking about representations of semantic objects. I'm talking about representations of syntax . In Lisp's case, you don't get to choose - the macro system critically depen…
(Can't we expand macros in a conventional representation with symbols and environments and then go to HOAS?)
(It's not news that macros are weak in some sense; I mean you can shoot yourself in the foot with the classic non-hygienic ones; you can disrespect even the first order abstract syntax that you're working in: the macro can re-locate a piece of raw syntax which contains identifier references into the wrong scope where those references resolve otherwise.)
Anyway, have fun fishing for mackerel with your bear trap?
Re: Swift and the Legacy of Functional Programming
#180Earlier quoted context omitted.
> Do you get the difference between internal and external representations? When you see (lambda (a) (+ a 1)), you don't know how the code is represented internally and how its value, when executed [emphasis mine], is represented internally I'm not talking about representations of semantic objects. I'm talking about representations of syntax . In Lisp's case, you don't get to choose - the macro system critically depen…
> In Lisp's case, you don't get to choose - the macro system critically depends on a particular representation (named variables) Please tell me how Haskell represents HOAS and how this is not possible in Lisp. Also, read Barzilay's paper ( http://scheme2006.cs.uchicago.edu/15-barzilay.pdf ), or about the Ergo Project (1988! http://repository.cmu.edu/cgi/viewcontent.cgi?article=2763&c... ).
I'm not talking about representing some object language's syntax in Haskell or Lisp. I'm talking about representing Haskell or Lisp's syntax in some other metalanguage (possibly Haskell or Lisp itself). How would you implement a macro expander that operates on HOAS?
> Barzilay's paper (http://scheme2006.cs.uchicago.edu/15-barzilay.pdf)
The object language implemented in that paper isn't the whole of Scheme, and in particular, it doesn't have macros.
> Ergo Project (1988! http://repository.cmu.edu/cgi/viewcontent.cgi?article=2763&c...)
Sorry, I can't find an explicit description of any object language's syntax in this paper.