I hope I don't get kicked out of HN altogether for this comment :)
Luckily all of them can coexist, so we do not need to choose.
My relative use of Lisp languages: Common Lisp 60%, Racket 20%, Haskell 5%, Clojure 5%, and various other Schemes 10%. Unfortunately since most of my work in the last 8 years has been deep learning, LLMs, LLM chains, etc., I spend a little over half my time now using Python. So it goes...
I don't think it's a particularly unique or interesting quality, that some old code still runs. After all, I can go to archive.org right now and run all of that ancient DOS, Amiga, whatever code in a 100% exact (or close to) emulator in my browser.
(compiled-function-p #'f) ; T
(disassemble 'f)
; disassembly for F
; Size: 58 bytes. Origin: #x5350CD14 ; F
; 14: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer
; 18: 488945F8 MOV [RBP-8], RAX
; 1C: 4883EC10 SUB RSP, 16
; [...]
$ pmap $PID --range 5350CD14
442331: /usr/bin/sbcl
0000000053498000 122272K rwx-- [ anon ]
total 122272KIt looks like that wasn't the case even in 1996:
But if you mean "compile a new function called X and replace the old X at runtime", that's easy in Common Lisp. It's not commonly done unless you're explicitly writing some kind of compiler.
What is commonly done is to create a lexical closure at compile time and change its bound values at runtime. IOW changing the private data of a function at runtime is more generally useful than changing its instructions.
What's most common is to write lisp programs that emit lisp source code and compile it at compile time (but usually not run time). Such programs are called macros.
In SBCL, any evaluation of an expression is done by first compiling it. Compiled functions that are no longer accessible (including not having any frames on the stack) are garbage collected.
The really interesting question is not whether users can mutate existing compiled code, but whether it's useful for the Common Lisp implementation to do so. This is because Common Lisp is a dynamic language, where generic functions and classes can be redefined on the fly. If you want to implement such things efficiently, it would be useful to be able to change existing compiled functions to reflect that (for example) this slot of this object is at this offset rather than that offset.
A scheme has been proposed to do that that puts such code off to the side in little chunks accessed with unconditional branches. When a redefinition occurs the branch is redirected to a newly created chunk; the old one is GCed when no longer referenced from the stack. You have to pay for the unconditional branches, but those are typically quite fast.
You compile code, which is text (data), all the time, don’t you?
These days, a page of memory can be set to
Read Write Execute
The exploit mitigation you refer to is having the program typically set pages of memory to never have both write and execute set at the same time.
However, this is ultimately controlled by the program. On Linux, the program can invoke the os call 'mprotect' to change the permissions on a page (though a program can also voluntarily use seccmp routines to forego ever invoking this ever again)
And this is basically what browsers do. They compile the code into memory that has been set to 'write' (but not execute) and proceed to then set it to execute (but not write).
The effectiveness of this mitigation is mitigated by the existence of ROP techniques, which is why Intel started introducing Control-flow Enhancemnent Technology (CET), which is intended to ensure you can only branch to certain locations in memory.
unfortunately running on JVM actually really means running on Java same for .net it mean running on C#
i dont mind learning two languages, its expected from most developers to know more than one, but context switching in a single function between two language is not fun
However F# suffers from a bigger issue, that clojure doesn't, belonging to the platform owner, that behaves as if it was an error to make it part of VS 2010.
And I dont think F# failed, I just think it needs to find a way to hide C# and OOP better
But the language is doing fairly well, tons of educational resources, tons of videos on youtube , several nice projects on github, solid vs code mode, it is part of .net , but still a lot can be improved, and microsoft is far from abandoning, C# is one of MS flagship products , F# is not a flagship product
And I also think that Don Syme is a lot more active working for F# and promoting it, than Rich Hickey is currently working for Clojure
> microsoft is far from abandoning
Might has well. When you look at the resources actually being deployed for F#, it's clear that MSFT either don't care or don't really have plan for F#. Most of the work is done by the community. The number of actual paid/full time MSFT dev on F# is very limited. The tooling is extremely limited, there is no official F# libraries for pretty much any MSFT and azure services (have to relie on C# libs.) In leetcode where the have C# (so already have the infra to run .net stuff, and language like elixir and racket (so they do have more niche language), they still don't have F#.
The salvation for F# would come from finding a killer app, something akin to pytorch/numbpy or rails.
In my opinion, and I mean this in the broadest way possible, the average C# developer is probably less motivated to learn a new language than the average Java developer. That's because C# developers are prescribed by Microsoft what to do, and Microsoft could deliver a productive-enough experience with C# + .NET Framework + Visual Studio for a long long time.
Java's fractured IDE story and runtime (OpenJDK vs. HotSpot) I think lead to a higher concentration of programming language people looking at the JVM as a viable target to build a better experience on top of, so we got Groovy, Scala, Kotlin, (anyone remember Xtend?), IDEA, Eclipse, etc...
The bazaar produced and embraced a functional programming language whereas the cathedral treats F# as thunderdome for new C# features.
F# can do OOP just as well if not better than C#, and F# is anywhere from 2-10 times more concise than C#.
That being said, the mistake of Microsoft was viewing F# as a competitor to and research lab for C# and the community for viewing and selling it as a replacement for C#.
What Microsoft and the community should have done is treated F# as a competitor and replacement for Python from the start.
Every language lives under the iron fist of libc and the C ABI.
I know F# quite well at this point but only barely know C#. I know C# maybe only mildly better than C++ or Java in terms of being able to read it and guess what it's doing. I certainly can't write in it without looking up a bunch of stuff.
It’s too bad, because itself is really terrific.
Comparing to other languages I think the stability of the language has served the user community really well and been an enabler of the ecosystem. I guess the continuous language additions and resulting complexity & library/framework chuirn in some otherlanguages can also be seen as vitality and growth, but for many of us it's the wrong kind of growth.
(And yes there are also disadvantages to the centralised development model of the core language)
edit: there's a good summary of the discourse surrounding this post in the reddit comments at the time: https://www.reddit.com/r/Clojure/comments/a0pjq9/rich_hickey...
The usual "expect all for free, give nothing back" attitude.