HN user

_19qg

12,722 karma
Posts7
Comments102
View on HN

If the Axis powers had won the war all the countries of Europe would have had even deeper "cooperation"

There you've placed a link from Fascism and "National Socialism" to the EU.

Nice try.

But the post I replied to implied that socialist=social democratic

That's actually largely the case in Western/Middle Europe.

marxist/communists in the far-left parties (and sometimes the whole party)

Which are often not seen as socialist. Social/socialist typically signals that the party is inside the system supporting political spectrum. "communist/marxist" usually signals that the party is at least partly outside the system supporting political spectrum.

ultra-right parties may have "socialist" in their name, but they are typically not in a sense connected to Marx&Hegel. Example: the "National-Sozialistische Deutsche Arbeiterpartei" (Hitler's NSDAP) was not marxist.

For the US reader:

39 MPs in the Bundestag

Out of currently 733 MPs with a parliament with "proportional representation", where the number of seats is proportional to the number of votes (Germany-wide, not local). Die Linke thus has 5.3% seats in the Bundestag. Thus this is not "a lot of votes" in relation to the voting population.

"anti-capitalist" (which seems to be more popular than claiming to be socialist)

Anti-capitalism is found in right-wing parties, too. Like the German AFD.

We Are the Robots 2 years ago

There is a idea of a robot (on the album "Die Mensch-Maschine", "The Man Machine") as the perfect worker (russian "rabotnik") and also the relationshop to russian suprematism as an art form (see the cover).

The robot as an ideal socialist worker.

Lyrics:

    Я твой слуга (Ja tvoi sluga) (I'm your slave)
    Я твой работник (Ja tvoi rabotnik) (I'm your worker)
M4 MacBook Pro 2 years ago

I'm using them for several years - I still have a Mac mini (from 2012) and an iMac Pro (from 2017) running. I also get a company Macbook which I can upgrade every three years.

But there is also another strategy: get a new Mac when they come out and sell it before/after the next model appears. There is a large market for used Macs. A friend of mine has been doing this for quite some time.

M4 MacBook Pro 2 years ago

It's a very robust and capable small laptop. I'm typing this to a M1 Macbook Air.

The only thing to keep in mind, is that the M1 was the first CPU in the transition from Intel CPUs (+ AMD GPUs) to Apple Silicon. The M1 was still missing a bunch of things from earlier CPUs, which Apple over time added via the M1 Pro and other CPUs. Especially the graphics part was sufficient for a small laptop, but not for much beyond. Better GPUs and media engines were developed later. Today, the M3 in a Macbook Air or the M4 in the Macbook Pro have all of that.

For me the biggest surprise was how well the M1 Macbook Air actually worked. Apple did an outstanding job in the software & hardware transition.

I'm probably failing to consider edge cases but it seems like a potentially simple tweak that might make lisps more palatable to many

Lisp came out in 1960. The s-expression-only syntax was an accident or a discovery - depending on one's view. Over the many years no attempt to add significant indentation syntax without parentheses gained more than a few users. Syntax variants without parentheses (and no significant indentation) only had a marginally better fate. Sometimes it even contributed to the failure of Lisp derived languages (-> Lisp 2, Dylan)...

Generally I agree with what you are saying. I live outside the US and so this stuff from the end 70s / early 80s was very remote. Gladly we had then a well connected university where I got in contact with some of the more interesting stuff mid 80s.

The book I found most useful in the early times as an introduction to Lisp and programming with it was LISP from Winston & Horn. The first edition was from 1981 and the second edition from 1984. I especially liked the third edition.

https://en.wikipedia.org/wiki/Lisp_(book)

Lisp on microcomputers in the early 80s was mostly not useful - that was my impression. I saw a Lisp for the Apple II, but that was very barebones. Next was Cambridge Lisp (a version of Standard Lisp) on the Atari ST. That was more complete but programming with it was a pain. Still, I found the idea of a very dynamic&expressive programming language and its interactive development style very interesting. The first useful implementations on smaller computers I saw were MacScheme and Coral Lisp, both for the Macintosh, Mid 80s...

There were articles about Lisp in the Byte magazine early on, but having access to the software mentioned was difficult.

The early use cases one heard of were: computer science education, functional programming, generally experimenting with new ideas of writing software, natural language processing, symbolic mathematics, ... This was nothing which would be more attractive to a wider audience. David Betz Xlisp later made Lisp more accessible. Which was then used in AutoCAD as an extension language: AutoLisp.

Luckily I had starting mid 80s access at the university to the incoming stream of new research reports and there were reports about various Lisp related projects, theses, etc.

I had a 30 meter (IIRC) console cable for my 3640.

Most University labs had a machine room where the Symbolics machines (if they had those) were standing (large, too noisy fans, drawing 1 kw or more electricity, ...). Cables for the console (1 Megapixel b/w screen, keyboard, mouse and digital audio) went from there into the offices. All one could hear were the clicks from the Symbolics mechanical keyboards.

The LMI and Explorer machines had some interesting hardware stuff. Too bad, that both companies left the business very early ...

Accelerators were available for the Symbolics machines, too. IIRC there were DSPs. Also an interface to the Pixar Image Computer and to Connection Machines. Or the FrameThrower, a programmable Framebuffer.

The first (big) AI winter he refers to was in the mid 70s.

The 80s (mid/end) AI winter have had an effect on private companies, but it was also mostly because of government funding was reduced/eliminated, where their revenue was coming from. Much of the revenue of the computer hardware and software companies in the 80s AI bubble was coming from government funding, like the Strategic Computing Initiative and the Strategic Defence Initiative ("Star Wars"), both running from 1983 until 1993, with various levels&aims of funding. That was a part of the effort to win the cold war (here by investing huge amounts of money into modern weapons & defense systems, which meant also into computing and AI) with the Soviet Union , which eventually collapsed, end 80s - early 90s. Also many of the promises of the AI technology did not materialize -> the private sector did not take over the funding.

Xah Lee wasn't a part of the Lisp community. He was a Usenet troll, active in several programming related newsgroups, not just comp.lang.lisp. He had never written a line of Lisp (or anything more challenging) and never contributed anything, during his Usenet times. His effect on these newsgroups was extremely negative. Discussing with him was useless. Erik Naggum tried and failed (as others did). Erik was a part of the Lisp community, but unfortunately also with negative behavior, especially on comp.lang.lisp. He could write long&useful explanations, but discussions with him were often not pleasant.

Whether or not computation behind the scenes happens at some particular time (read/compile/run) isn't too relevant.

Actually it is relevant: is the object mutable? Are new objects created? What optimizations can a compiler do? Is it an object which is a part of the source code?

If we allow [1, 2, (+ 1 a)] in a function as a list notation, then we have two choices:

1) every invocation of [1, 2, (+ 1 a)] returns a new list.

2) every invocation of [1, 2, (+ 1 a)] returns a single list object, but modifies the last slot of the list. -> then the list needs to be mutable.

    (defun foo (a)
      [1, 2, (+ 1 a)])
Common Lisp in general assumes that in
    (defun foo (a)
     '(1 2 3))
it is undefined what exact effects the attempts to modify the quoted list (1 2 3) has. Additionally the elements are not evaluated. We have to assume that the quoted list (1 2 3) is a literal constant.

Thus FOO

* returns ONE object. It does not cons new lists at runtime.

* modifying the list may be not possible. A compiler might allocate such an object in a read-only memory segment (that would be a rate feature -> but it might happen on architectures like iOS where machine code is by default not mutable).

* attempts to modify the list may be detected.

SBCL:

    * (let ((a '(1 2 3))) (setf (car a) 4) a)
    ; in: LET ((A '(1 2 3)))
    ;     (SETF (CAR A) 4)
    ; 
    ; caught WARNING:
    ;   Destructive function SB-KERNEL:%RPLACA called on constant data: (1 2 3)
    ;   See also:
    ;     The ANSI Standard, Special Operator QUOTE
    ;     The ANSI Standard, Section 3.7.1
    ; 
    ; compilation unit finished
    ;   caught 1 WARNING condition
    (4 2 3)
* attempts to modify literal constants may modify coalesced lists

for example

    (defun foo ()
      (let ((a '(1 2 3))
            (b '(1 2 3)))
        (setf (car a) 10)
        (eql (car a) (car b))))
In above function, a file compiler might detect that similar lists are used and allocate only one object for both variables.

The value of (foo) can be T, NIL, a warning might be signalled or an error might be detected.

So Common Lisp really pushes the idea that in source code these literals should be treated as immutable constant objects, which are a part of the source code.

Even for structures: (defun bar () #S(PERSON :NAME "Joe" :AGE a)) -> A is not evaluated, BAR returns always the same object.

Do you have any suggestions on how to talk about this "literal syntax" in another way that won't step on or cause confusion with the CL spec's definition?

Actually I was under the impression that "literal" in a programming language often means "constant object".

See for example string literals in C:

https://wiki.sei.cmu.edu/confluence/display/c/STR30-C.+Do+no...

Though it's not surprising that language may assume different, more dynamic, semantics for compound objects like lists, vectors, hash tables or OOP objects. Especially for languages which are focused more on developer convenience, than on compiler optimizations. Common Lisp there does not provide an object notation with default component evaluation, but assumes that one uses functions for object creation in this case.

simple version of the {} macro shown in https://news.ycombinator.com/item?id=1611453

That's not implementing a literal (an object that can be read), but a short hand notation for constructor code. The idea of a literal is that it is an object created at read-time and not at runtime.

In Common Lisp every literal notation returns an object, when read -> at read-time. The {} example does not, because the read macro creates code and not a literal object of type hash-table. The code then needs to be executed to create an object -> which then happens at runtime.

The ANSI CL glossary says:

https://www.lispworks.com/documentation/HyperSpec/Body/26_gl...

literal adj. (of an object) referenced directly in a program rather than being computed by the program; that is, appearing as data in a quote form, or, if the object is a self-evaluating object, appearing as unquoted data. ``In the form (cons "one" '("two")), the expressions "one", ("two"), and "two" are literal objects.''

    CL-USER 4 > (read-from-string "1")
    1
    1

    CL-USER 5 > (read-from-string "(1 2 3)")   ; -> which needs quoting in code, since the list itself doubles in Lisp as an operator call
    (1 2 3)
    7

    CL-USER 6 > (read-from-string "1/2")
    1/2
    3

    CL-USER 7 > (read-from-string "\"123\"")
    "123"
    5

    CL-USER 8 > (read-from-string "#(1 2 3)")
    #(1 2 3)
    8
But the {} notation is not describing a literal, it creates code, when read, not an object of type hash-table.
    CL-USER 9 > (read-from-string "{:foo bar}")
    (LET ((HASH (MAKE-HASH-TABLE))) (SET-HASH-VALUES HASH (QUOTE (:FOO BAR))) HASH)
    10
This also means that (quote {:a 1}) generates a list and not a hash-table when evaluated. A literal can be quoted. The QUOTE operator prevents the object from being evaluated.
    CL-USER 13 > (quote {:a 1}) 
    (LET ((HASH (MAKE-HASH-TABLE))) (SET-HASH-VALUES HASH (QUOTE (:A 1))) HASH)

    CL-USER 14 > '(defun foo () "ab cd")
    (DEFUN FOO NIL "ab cd")
In above example the string is a literal object in the code.
    CL-USER 15 > '(defun foo () {:foo bar})
    (DEFUN FOO NIL (LET ((HASH (MAKE-HASH-TABLE))) (SET-HASH-VALUES HASH (QUOTE (:FOO BAR))) HASH))
In above example there is no hash-table embedded in the code. Instead each call to FOO will create a fresh new hash-table at runtime. That's not the meaning of a literal in Common Lisp.

LISP is short of "List Processor". It was developed as a language & system for processing lists. The programming language LISP was supposed to have M-Expressions (M -> Meta) for code and S-Expressions for data. For example a call to append two lists would have looked like this:

    append[listvar;(PARIS BERLIN NEWYORK TOKYO)]
The arguments are enclosed in square brackets. The second argument is written as an S-Expression. S-Expressions were the data notation and were enclosed in parentheses. Symbols were upper case. The names of operators and variables were lower case.

The append call then looked like this:

    (APPEND LISTVAR (QUOTE (PARIS BERLIN NEWYORK TOKYO)))
A conditional would have been:
    [eq[car[l];0] → cons[(ZERO);cdr[l]]; T → x]
Which in S-expression only syntax is:
    (COND ((EQ (CAR L)) (CONS (QUOTE (ZERO)) (CDR L)))
          (T X))
As you can see the conditional would have a special infix syntax.

Because of the limitations of the character sets available in old computers, the round parentheses have a dual role in LISP, as delimiters for lists that are data and as delimiters for the lists of arguments used by function/macro invocations.

No, the syntax above wasn't actually implemented at first. The M-Expression/S-Expression combination was hand translated into S-Expressions, since the Interpreter and Compiler took lists as input.

The reason why the syntax is like this is not a lack of characters or so. The reason is because the language early on worked on code as list data and not on code as text. The input and output was then of list data. The famous "Read Eval Print Loop" reads data, evaluates it and prints the result in data format.

It was thought that a later version of LISP had the M-Expression/S-expression syntax as surface syntax. But that did not get any traction, because the S-expressions would be visible in the programming tools anyway: debugger, code inspector, code stepper. Thus it was more convenient to stay in the s-expression syntax, than to convert S-Expressions both from and into M-Expressions/S-Expressions.

For example a stepper for LISP code might look like this. :s is the single step command:

    CL-USER 8 > (step (plus (minus 10 20) (plus 20 30)))
    (PLUS (MINUS 10 20) (PLUS 20 30)) -> :s
       (MINUS 10 20) -> :s
          10 -> :S
          10 
          20 -> :S
          20 
          (- A B) -> :s
             A -> :S
             10 
             B -> :s
             20 
          -10 
       -10 
       (PLUS 20 30) -> 
and so on. The interpreter internally sees Lisp code as lists and just prints the lists while it steps the code...

If we wanted M-Expressions, then the things would needed to be converted everywhere/everytime, which is much less elegant than leaving everything in one notation.

LISP 2 was an effort to modernize LISP and to switch to a different syntax.

People seem to use Lisp like it is some impoverished programming model. Why would I want to do things concurrently in one Lisp? Because that's how I use a Lisp system all the time. That's my normal way to do things.

But you mean a REPL as in a console-style interaction, right?

I mean > 1 REPL as an example how I would use a Lisp concurrently. Yeah, I can switch between REPLs in micro seconds and run > 1 second activities in each of them.

Any command used in Emacs is an eval step in a REPL

And you can't run simple Lisp code in two commands concurrently, neither in a REPL nor in a command.

`while-no-input`

Type (while-no-input (dotimes (i 1000000) (print i))) in two Emacs Lisp repls and have them running concurrently.

I understand that GNU Emacs can run external processes, external instances of GNU Emacs, external other Lisp systems, that it can provide some limited form of cooperative threads, ...

I have lived through this stuff 30 years ago and onwards, when many Lisp implementations used cooperative threading (and some had cooperative threads deeply integrated in their Lisp code, other than GNU Emacs in 2024) and over the years switched to native preemptive threading. I also remember when we got Symmetric Multiprocessing in several Lisp systems roughly 15 years ago.

Certain points like the fact that Emacs isn't multithreaded are thrown around by people who don't have the intuition that multithreading isn't the right thing for a lot of applications.

GNU Emacs has a lot of applications where it is the right thing. It's no longer the simple editor. It comes with more than a million lines of Lisp code implementing all kinds of complex features: like various network client applications, IDEs, ...

Common Lisp+SLIME shares some of this convenience, but not to the extent that Elisp truly does

SLIME is mostly implemented in Emacs Lisp. A lot of other Lisp systems can locate all source code and all documentation. It's not so much a special feature of Emacs Lisp, but its development environment. It's also not necessary that the IDE and Lisp runs in the same process / same machine to be able to look up documentation and code. It may be convenient in GNU Emacs, but any such editor can provide such features for programming language implementations.

They didn't get very far with anything more realistic. A lot of the plans and policies were caused by the development of the war. Hitler himself was not an economist. His background was art and military. His hobby was city architecture and military strategy...

A large scale area in Eastern Europe was dreamed about (-> upto 1933) and in 1939 the war started with the attack on Poland to realize this war for Lebensraum, where the Germans then would be the elite race and the others were slaves (or dead). This east european region would provide food, energy, raw materials, ... There were ideas about what this large "Reich" would be like. But that was not close to be realized, given that Germany was deeper in war with every day, on two sides, 1941 onwards: in the east in the Soviet Union and against a US lead war in the west. Germany was busy fighting the war.

43/44 some German economist were beginning design an economy in more detail for a time after a war. But it then became clear that it was after a lost war (with the Nazis no longer in power) and that this time probably was not far away, with then the war being lost in 1945.

I wonder how Nazi-Germany would have worked out without antisemitism.

That was often heard in Germany after the war. Hitler's politics were not seen as bad, if only the jews were not killed. Often, it was mentioned that Hitler's achievement was to reduce the mass unemployment after getting to power in 1933.

"Nazism" is defined by more than "antisemitism" -> https://en.wikipedia.org/wiki/Nazism

* the main goal of the Nazis was to conquer and enslave East Europe.

* for that the Nazis transformed Germany into a war machine

* the war to enlarge Germany was the defining goal and everything was forced to support that goal

* generally Nazi ideology was racist and brutal. There were lots of groups which were to be killed and/or enslaved.

* it was a Dictatorship with Hitler as a "Führer"

Even if Nazi Germany were not "antisemitic" it would still have started the war in the East to conquer East Europe as a colony (-> "Lebensraum" -> https://en.wikipedia.org/wiki/Lebensraum ).

privatization and killing unions under Hitler.

That was not defining for the economic policies under Hitler. See https://en.wikipedia.org/wiki/Economy_of_Nazi_Germany

The Nazi economic policy had one goal in the early years: forcing the German economy to concentrate on wartime preparations. Building up the military power and the military economy. All the companies were forced to work towards that goal. Many Germans were put into forced labor ("Reichsarbeitsdienst", ...) to support the build-up of the military and the military economy.

Large amounts of weapons had to be developed and produced: for Heer, Luftwaffe and Kriegsmarine.

The goal was to be ready for a large-scale war in the East in just 4 years.

With the war started, the economy was mostly a state-directed war economy, private or not. Even though there were large private companies they were all directed to work for the war economy.

The Nazis themselves were also involved in large scale industrial production. The Concentration Camps were also producing for the military. "Vernichtung durch Arbeit" (-> https://en.wikipedia.org/wiki/Extermination_through_labour )

That the Nazis were supported by leaders of the German industry did not mean that the Nazis were interested in privatizing, market economies or such. There was one goal: reorganizing the German economy to build-up and run the large scale war in the East. The goal was to colonize and enslave East Europe. Finances were concentrated on the war economy and other economic activities were no longer important or even possible. Companies involved would profit from it financially and expand. Companies involved in private sector activities would have a hard time. For example finances and raw materials was with priority allocated to the military economy.

You'll need to say what this "lisp" and the "lisp features" are.

When we go back to the original idea of LISP, we have the following things:

idea -> what follows from those

1) programming with Symbolic Expressions -> support the implementation/implementation of languages

2) "programming with Symbolic Expressions" applied to itself -> Lisp in itself, code as data, macros, self-hosting compiler, Lisp interpreter

3) linked lists and symbols as data structures for Symbolic Expressions

4) a programming system to build algorithms and programs based on the ideas of above -> symbols repository, late binding, recursive functions, symbols with properties, garbage collection, Lisp interpreter using s-expressions, Lisp compiler, reader, printer, read-eval-print-loop, a resident development environment, managed memory, saving/loading heap dumps, dynamic data structures,...

LISP means "List Processor" (not "List Processing"). Which indicates that this is at its core, not a library or an add on.

There aren't that many other languages which are based on these ideas.

We can define three levels of "feature adoption":

* enables a feature (the language provides mechanisms to provide a feature)

* supports a feature (the language actually includes those features, but use is optional)

* requires a feature (the language requires the use of that feature, its not optional for the developer)

If we use a programming system, which requires the four core ideas above (and many of the features that follow from those) and is based on them, it is still very (!) different to what most people use.

Example:

Smalltalk development was started more than a decade after LISP. It adopted a huge amount of features from Lisp: managed memory, resident development environment, garbage collection, late binding, interactive use, runtime evaluation, dumping&loading heaps, etc. etc. For a decade Xerox PARC developed a Smalltalk system and a Lisp system side-by side: Smalltalk 80 systems and Interlisp-D systems were the results.

Still: Smalltalk 80 did not use the first three core ideas from above and replaced them with another core idea: objects+classes communicating via message passing.

Thus mass feature adoption alone does not make Smalltalk fundamentally to be a LISP. Nor does feature adoption make a language popular.

So we can ask use, will those core ideas of Lisp make it very popular? Seems like it did not. Still many of the useful features which were following from it could be replicated/adopted/morphed into other languages.

The original article was probably taking a view that a language&programming system which enables domain specific embedded languages would be "better" than the diverse stack of tools and languages in the automotive domain. Lisp is such a tool for embedded languages (embedded into a hosting language, not in the sense of languages for embedded systems), but that does not make it the best for that domain, which has a lot more requirements than language embedding (like reliability, robustness, etc. ...). In Germany A-SPICE gives a lot of hints what a development process needs to do, to deliver reliable software for the automotive domain. I don't think Lisp would fit well into such a development process.

Rye Language 2 years ago

Lisps use Macros

IF is a built-in special operator in Common Lisp. COND is a macro, which expands into IF forms.

(if (> x 1) '(print 'larger))

Stuff like this would not really work Common Lisp for the following code example:

    (let ((x 1))
      (if (> x 1)
        '(print x)))
The evaluator would not know that the X in the print form refers to the lexically bound X from the LET form.

"pseudo-Marxist" ? LOL, you have no idea what you are talking about. I'm arguing for a smaller-scale energy landscape, for privately owned enterprises, individuals, etc. If that is Marxist, you are seriously confused.

EVEN if I were to buy solar panels from China, then I'm still financing them, I'm buying them, I'm installing them, I'm operating them, I'm selling the energy and the profits from solar electricity is MINE - over the full lifetime. Solar energy production is more than "chinese panel manufacturing".

The nuclear reactor Flamanville/France, which has massive cost overruns and delays:

  * controlled by the state
  * financed by the state
  * bought by the state
  * constructed by the state
  * operated by the state
  * energy sold by the state
EDF (Electricité de France) is government owned and builts and operates the power plant, it also sells the electricity to the customer.

ALL, literally all, of the electricity production and distribution from French nuclear power plants is owned by the state. That's Marxian!

If I see where I live, the Wind Farms serving the region:

https://en.wikipedia.org/wiki/List_of_offshore_wind_farms_in...

The construction firms for Wind Turbines are Vestas, Siemens, etc. These are not state owned. They are private enterprises.

Example, the German Wind Farm "Kaskasi". The Turbines were built by Siemens. The Wind Farm is owned by RWE, a private enterprise. https://www.rwe.com/en/the-group/countries-and-locations/off...

Energiewende is also financed with state money

The Energiewende had established a mechanism where the consumer pay higher prices (which you have lamented about), which finances the build-up of renewable energy -> the money goes to the renewable energy electricity providers, which are private enterprises and individuals.

The energy companies, the grid, the construction companies, etc., none are owned by the German state. These are all private enterprises or local municipal utilities.

The way Apple handles storage and memory means ENTIRE devices need to be replaced when a new larger SSD or a few more gigs of memory are all that's really needed to keep a device in service for a few years longer.

Most iPads are vastly overpowered and last for a long time. If someone needs more power/storage, then one usually passes them to the next person which might use it for many more years.

My old iPad Air 2 from 2024 is still used.

Even the iPad could probably use an M.2 SSD!

Most users don't need that. I'm using fixed storage in my Macs (and iPads) for years. I've attached additional storage to USB-C for many years without problems.