Actually, they thought that the Esperanto word for forge, is «forgejo». When somebody pointed out, that «forgejo» (fora gejo -> forgejo) is «faraway gay person», it was already too late. So, now they say that it is inspired by «forĝejo», which is the word for forge.
Plej verŝajne, neniu el vi ĉi tie komprenos ĉi tiun mesaĝon rekte, sen tradukiloj. Tamen, por oni kiuj povas kompreni min, mi devas diri, ke Esperanto vivas tial, ke la lingvo estas permesita por kreskiĝi nature. Jes, mi jam pruvis, ke la lingvo povas esti uzita en teĥnikaj konceptoj. Vidu mian profilon.
My very rusty Esperanto seems to still be able to get the gist of what you said (and I also understood the little I read of an article on your website).
My trouble is that whatever material I used to learn it (mainly Kurso de Esperanto and a course on lernu!) seemed to be completely detached from the way most people seem to actually write. Lots of suffixes I've never seen used in the learning material are abundantly used in the real world.
All of this to say, where do I go to learn a bit better?
My feeling is that the courses teach you the grammar pretty well, but you have to read (with a dictionary ready) to get more of what you are asking for.
As one may have already noted, that was precisely my goal. When I said no one, I meant it in the metaphorical sense. It’s not actually about uniqueness, but more of being less in numbers.
Not so much as a bad version of Common Lisp, but a half-baked Lisp. I am well aware that a response like this is bound to stir the opinions of other people about things like this, but I am also bound to express mine. There is not one correct response, and that everything can be considered subjective.
Clojure (on the JVM) is a lisp-y way to talk to the JVM and the rest of its ecosystem. Because it uses s-expressions, it allows for abstractions that are not possible otherwise. I have used Clojure myself in the past. It was fun.
However, there are still many things that are not polished in Clojure that are well-established in Common Lisp. The debugger of Common Lisp is one of the best out there. Its object system is also top class. Backtraces in Common Lisp allow you to get as much information as you can get from your program. Metaprogramming in Common Lisp is also out there in the top. The inverse, however, is not true. You need to have a PhD in JVM in order to read Clojure backtraces. You can easily create a program then dump it into a single executable with Common Lisp, not so much with Clojure. You want fast startup? Not with Clojure.
If you haven’t spent a significant amount of time with the different kind of lisps, it’s hard to make objective comparisons and judgement—everything that Clojure has would look cool and fancy.
I know some people who share the same sentiments that I have, who won’t reply to this thread. However, I’m a fool to even write this response.
Ouch! We had that bug in early testing and thought it was fixed. Hit it once more from the home page if you would and we'll look into it. Thanks for letting me know.
Thanks for the feedback! I just replied to your opened Github issue (the app requires more RAM to function than your docker can allocate - you can add more memory via docker engine settings).
Estas interese, ke je Hacker News ĉi tiu afiŝo atingis.
La parolantojn de aliaj lingvoj, preciple la angla-parolantojn mi ne plu kuraĝigas por Esperanton lerni. Estas malŝparo de energio. Anstataŭe, la lingvon mi uzas sen tiu celo.
Bedaŭrinde, mi ne certas se bonan diskuton pri tiu temo ni povas havi ĉi tie. Se estas parolantoj ĉi tie, mi anticipas ke la nivelo malaltas. Espereble, pli fortan diskuton mi povas havi aŭ vidi.
Kompreneble, mi povas konsenti ke fortas Esperanto. Min mem mi farigis kavio. Mi volis scii, se fakte utilas tiu lingvo. Post preskaŭ kvar monatoj, mi konsciis, ke mi pravis. Jes, fakte funkcias Esperanto. Jes, eĉ la plej bizarajn ideojn mi povas esprimi Esperante. Jes, la lingvon mi subtenos en miaj restantaj jaroj.
The key problem with this article is, that Norvig cherry-picked features of Lisp that are present with the languages that he contrasts it with. So, what happens then is that it will give the impression that Lisp somehow lost its uniqueness, or whatever makes it stand out among the others. The premises were at best, loaded.
If we’re going to talk about CL, here are some of the features that still make it unique:
- live update of a running program, including (re)definitions of classes, condition handlers, etc.
- object system which has multimethods, multiclasses, multidispatch.
- it has a debugger and stepper which has complete access to the stack, with unwind protection
- it has a very strong, unhygienic macro system.
The average programmer does not need a lot of these things because:
- the tasks do not demand those features
- the programmer doesn’t know them
- the programmer doesn’t want to or can’t invest time in them
Smalltalk has live update of the running program, arguably in a much better way than (modern) Lisps. In Smalltalk you edit code directly in the running image, there's no possibility of defining a function in the REPL and having a different definition in a source file somewhere: the source is the image, and any change to code is reflected in the image. The old Lisp machine Lisps (like Interlisp) used to do this too, I think, but no CL implementation I know of does this anymore.
The Smalltalk debugger is famously also implemented in the development image (and implementing a simple debugger is a common project in Smalltalk textbooks). Traversing the stack, accessing locals, stepping, etc. are of course all possible.
No CLOS in Smalltalk admittedly, but lots of shenanigans are possible by fiddling with the object model.
Likewise no macros, but Smalltalk syntax is so minimalistic that creating control structures that look like the built-ins is trivial. In fact, conditionals, loops and the like are entirely unmagical in Smalltalk (modulo performance optimizations to make things go fast); reimplementing conditionals (that look and work exactly like the standard set) for example is trivial.
Actually I thought the sources are stored in a source file and a corresponding changes file. True, one could de-compile the byte code - but usually the Smalltalk editor uses the sources from the sources/changes files.
Smalltalk actually tracks the editing operations / class operations and uses the sources/changes file as a simple code database.
> there's no possibility of defining a function in the REPL
If I programmatically create a class in Smalltalk, is it recorded in the source?
> Traversing the stack, accessing locals, stepping, etc. are of course all possible.
we do that in Lisp, too - the difference is that there is no virtual machine specified and none is common. The default mode of executing Lisp is a) interpreting or by using compiled code (usually to machine code, or to C and then to machine code, ...). There are virtual machines, but they are usually tied to a specific Lisp implementation.
The code is obviously stored somewhere, but that's not a user-facing place. Thus, if you define a function in the Smalltalk REPL equivalent (a workspace), when you open that function in the code editor later, you'll see the definition from the REPL, which is the interesting point. There's no way to have one definition on foo in foo.lisp and a different definition actually running in your image because you did a `(defun foo() ...)` from the REPL.
> If I programmatically create a class in Smalltalk, is it recorded in the source?
There's no distinction between programmatically created and other elements. Using the UI to create a class is just a front-end to the metaprogramming facilities you'd use to do it yourself at runtime.
> you'll see the definition from the REPL, which is the interesting point
whose source was put into the changes file
It's managed source code, but the source code is not in the image itself. Smalltalk tracks the connection and creates change records for changes done by meta-programming.
That's for example slightly different with a residential system like Interlisp-D / Medley, where the code is in the image itself, the editor is a structure editor actually editing it and the system can run either the source directly (via the Lisp Interpreter) or a compiled version of it.
But that method is not very popular in the Lisp world, where images are used, but changes are not tracked. Most Lisp development only track location of things. Changing sources is also not connected to quitting an image. It's a separate operation. Lisp also never bought into mostly a single development style/environment like Smalltalk did.
The main problem I had when learning CL was its standard library that at felt both enormous and strangely deficient in utilities for day-to-day work. CLHS is fine but the definitions can be obtuse, navigation isn't all that easy, and it's just a generally daunting approach to learning a language. There's a big gap between the code you learn in Practical Common Lisp and what you see if you open the source for any popular CL library.
It's like Haskell, without the hype. The underlying paradigms aren't that terribly different, but the actual terminology for expressing ideas idiomatically is wildly different, and represents an unusual obstacle.
>The underlying paradigms aren't that terribly different, but the actual terminology for expressing ideas idiomatically is wildly different, and represents an unusual obstacle.
Haskell uses a lot of terminology that's familiar to mathematicians, but unfamiliar to everyone else.
CL uses a lot of strange terminology, because it incorporated concepts before their names were standardized and used in other languages. You're left spending a lot of time trying to figure out that a wheel is called a frob or you just end up re-inventing the wheel even though the frob was already in the standard.
Also, he writes 'Python's object model is the same as Lisp's' which makes me think either he doesn't understand object models (really, really unlikely) or that he & I understand the phrase 'object model' to indicate very different things (more likely).
I think 'object model' refers to e.g. how classes, instances & methods work together; Lisp & Python have radically different object models.
Maybe he uses it to mean something like 'type model'?
Reading https://norvig.com/python-lisp.html this morning, it appears that my conjecture is correct: Norvig uses 'object model' to mean something like 'everything is an object,' 'objects have type, variables don't' & 'introspection of objects & classes is strong.'
In that sense, Python & Lisp are similar. But I don't think that's a good use of the phrase 'object model'; I think it's more usefully applied to the model objects follow.
The really radical difference between the Lisp & Python object models is that Lisp objects don't have methods. Where in Python one adds methods to a class, in Lisp one specialises generic functions on classes — and one isn't limited to specialising on a single argument. There's no clean way in Python to implement a method that works with a Foo and a Bar: one can either implement a method on a Foo that takes an argument of any type, or a method on a Bar which takes an argument of any type (although ISTR some rumours of typed Python; dunno how that would change things, but the methods would still live inside one class or another).
In Lisp, though, generic functions are their own things: they don't live inside a class at all. One would just specialise a generic function taking two arguments such that one is a foo & one a bar.
The difference is between this:
class Foo:
def baz(bar):
# bar might or might not be an instance of Bar
class Bar:
pass
or this:
class Foo:
pass
class Bar:
def baz(foo):
# foo might or might not be an instance of Foo
and this:
(defclass foo () ())
(defclass bar () ())
(defmethod baz ((foo foo) (bar bar))
;; foo is always a foo & bar is always a bar
)
This is so unlike Python as to be unrecognisable.
There's another difference, which used to drive me crazy in Python: when I redefine a class in Python, existing instances don't get updated, so if I had a REPL with a lot of state I'd have to manually convert the old instances to new ones. But with Lisp this happens automatically, and if one needs to run extra code (say, because the old & new class differ in an important way) then there's UPDATE-INSTANCE-FOR-REDEFINED-CLASS. That, BTW, is a generic function.
That's something I really like about Lisp: like SmallTalk, it's built for programming in the large, on stable systems which have to run for a long time. 'Just reboot it' is not a very Lispy idiom.
'object model' in Lisp has two traditional meanings. Originally data with identity is called an object. A cons cell, a vector, a string, some numbers, characters, symbols, ... all these are objects. One can reference any of them via variables, can return them from functions, give them as arguments to functions. Arguments are not copied. Function results are not copied. Etc. The JVM for example has a similar 'object model' like Lisp - thus the GLS quote: Java developers were half-way dragged to Lisp.
The second meaning is the object model in the sense of 'object oriented programming'. One of the similarities might be the use of meta-classes. Generally though CLOS isn't that near to the class-based OOP object-model of Python. CLOS uses a mixed model of classes and independent generic functions (with multiple dispatch)...
I suspect, that when he meant they are the same, he wants to convince the reader about his thoughts and sentiments about it. Norvig is a highly regarded CL author and programmer. Cognitive dissonance is such a powerful phenomenon.
Other languages have copied features of Lisp, but they often have convoluted or bloated syntax. Lisp reminds me of "E=mc^2" and Newton's "F=ma": powerful ideas based on simple building blocks or formulas. These other languages may have mirrored Lisp's power, but NOT its simplicity.
I used paredit before, then I switched to smartparens. I have also tried parinfer, but I didn’t like the way it behaves. I share the sentiments of this blog post https://github.com/noctuid/parinfer-notes