[a / b / c / d / e / f / g / gif / h / hr / k / m / o / p / s / t / u / v / vg / vm / vmg / vr / vrpg / vst / w / wg] [i / ic] [r9k / s4s / vip] [cm / hm / lgbt / y] [3 / aco / adv / an / bant / biz / cgl / ck / co / diy / fa / fit / gd / hc / his / int / jp / lit / mlp / mu / n / news / out / po / pol / pw / qst / sci / soc / sp / tg / toy / trv / tv / vp / vt / wsg / wsr / x / xs] [Settings] [Search] [Mobile] [Home]
Board
▼ Settings Mobile Home
4chan
/g/ - Technology


Thread archived.
You cannot reply anymore.




File: 1790600869485188.jpg (83 KB, 1284x1525)
83 KB JPG
>Lisp is a family of programming languages with a long history and a distinctive parenthesized prefix notation. There are many dialects of Lisp, including Common Lisp, Scheme, Clojure and Elisp.

>Emacs is an extensible, customizable, self-documenting free/libre text editor and computing environment, with a Lisp interpreter at its core.

>Emacs Resources
https://gnu.org/s/emacs
https://github.com/emacs-tw/awesome-emacs
https://github.com/systemcrafters/crafted-emacs

>Learning Emacs
C-h t (Interactive Tutorial)
https://emacs-config-generator.fly.dev
https://systemcrafters.net/emacs-from-scratch
http://xahlee.info/emacs
https://emacs.tv

>Browse imageboards in Emacs Org-Mode
https://github.com/eNotchy/4g

>Emacs Distros
https://github.com/caisah/emacs.dz

>Elisp
Docs: C-h f [function] C-h v [variable] C-h k [keybinding] C-h m [mode] M-x ielm [REPL]
https://gnu.org/s/emacs/manual/eintr.html
https://gnu.org/s/emacs/manual/elisp.html
https://github.com/emacs-tw/awesome-elisp

>Common Lisp
https://almightylisp.com
https://lispcookbook.github.io/cl-cookbook
https://cs.cmu.edu/~dst/LispBook
https://gigamonkeys.com/book
https://lisp-docs.github.io
https://awesome-cl.com

>Scheme
https://scheme.org
https://standards.scheme.org
https://go.scheme.org/awesome
https://research.scheme.org/lambda-papers

>Clojure
https://clojure.org
https://tryclojure.org
https://clojure-doc.org
https://clojure.land
https://www.clojure-toolbox.com
https://mooc.fi/courses/2014/clojure
https://jafingerhut.github.io/cheatsheet/clojuredocs/cheatsheet-tiptip-cdocs-summary.html

>Other
https://github.com/dundalek/awesome-lisp-languages

>Guix
https://guix.gnu.org
https://nonguix.org
https://systemcrafters.net/craft-your-system-with-guix
https://futurile.net/resources/guix
https://github.com/franzos/awesome-guix

>SICP/HtDP
https://web.mit.edu/6.001/6.037/sicp.pdf
https://htdp.org

>More Lisp Resources
https://lisp.nexus
https://rentry.org/lispresources

(reset! prev-bread >>109871435)
>mfw no Clojure
>>
woops I fucked up the prev-bread reference
>>109979569
>>
File: [email protected] (2.57 MB, 1920x1200)
2.57 MB PNG
scheme
>>
>>110094279
total sexo
>>
Today I will map a car and car a cdr
>>
BUMP!
>>
comfiest clojure webshit framework I've seen so far:
https://github.com/dynamic-alpha/hyper
>>
Lisp has an easter egg only i know about...
>>
File: 1791160019914901.png (290 KB, 522x626)
290 KB PNG
>>110098233
>>
Clojure finally ships a normal CLI REPL
(not built in don't get too excited)
https://github.com/clojure/clojure-cli.repl
>>
>>110098233
share it with the class
>>
>>110101779
very nice. I also like that `ExceptionInfo` is now going to be present without explicit import.
https://www.youtube.com/watch?v=VU4i_3xSWn8
>>
File: farolero.jpg (26 KB, 307x297)
26 KB JPG
a conditions system, similar to Common Lisp's, in Clojure:
https://github.com/IGJoshua/farolero
>>
>>110098233
John?
>>
>>110103040
I appreciate Joshua's work but I still don't understand what this is good for
>>
It's all over, isn't it bros
>>
>>110104751
What makes you say that?
>>
>>110104962
My bad I'm just in that kind of mood. I like lisp and programming
>>
>>110105135
Alright
It isn't over, Anon
>>
>>110104310
niche error handling techniques. personally I wrote my own error throwing macro that I find serviceable enough (it just throws an ExceptionInfo with a certain schema for the exception data, and has some helpers for tests and shit).
>>
>>110105650
I want to expand on this a bit, because I find my approach interesting. The code below shows first what exactly my macro expands to, and then how much shorter the macro is. I walk the predicate to locate local variables, and put them into the exception data automatically so that you are not constantly writing error boilerplate.
; Normal Clojure.
(defn verify-password-is-good
[password confirmation-password]
(cond
(not
(string? password))
(throw
(ex-info "some message"
{:id ::verify-password-is-good

:predicate
'(string? password)

:predicate-id :password-not-string
'password password}))

(not
(let
[password-length
(count password)]
(<= 12 password-length 1024)))
(throw
(ex-info "some message"
{:id ::verify-password-is-good

:predicate
'(let
[password-length
(count password)]
(<= 12 password-length 1024))

:predicate-id :bad-password-length
'password password

'password-length
(count password)}))

(not
(= password confirmation-password))
(throw
(ex-info "some message"
{:id ::verify-password-is-good

:predicate
'(= password confirmation-password)

:predicate-id :passwords-not-equal
'password password
'confirmation-password confirmation-password}))))

; Same as above with my macro.
(defn verify-password-is-good
[password confirmation-password]
(my-lib/verify ::verify-password-is-good
(string? password)
:password-not-string

(let
[password-length
(count password)]
(<= 12 password-length 1024))
:bad-password-length

(= password confirmation-password)
:passwords-not-equal))
>>
>>110101779
>https://github.com/clojure/clojure-cli.repl
Very nice, but how much of a difference does it really make when run inside of Emacs? SBCL and Guile both have rather sparse REPLs out of the box, you cannot even do basic line editing. Yet it seems to suffice when combined with an external editor.

FWIW, here is a video that explains how to enable readline support for Guile (around 04:13):

https://www.youtube.com/watch?v=JAt2_7wmjLU
>>
>>110107203
idk how useful it would be for in-editor REPL shit, probably not at all (you really shouldn't be typing code manually at the actual REPL, instead you should be typing code in a buffer, then evaluating it with a keybinding).
I could definitely see it being useful for things like having an open REPL to a prod instance for shelling into to debug live systems
>>
>>110107263
Right, and I do not mean to dissuade the project or anything. In fact, it is very nice to see people spend some time on these things. Racket is an example of a Scheme which has a very nice REPL out of the box (persistent history, editor keybindings, multi-line editing, syntax highlighting, parenthesis matching, meta commands).

https://docs.racket-lang.org/xrepl/
>>
>>110107424
it would also probably be very useful for new Clojure devs that don't have an in-editor REPL set up yet (or are simply used to things like Python REPLs)
>>
File: hug.png (274 KB, 786x1080)
274 KB PNG
>>110105135
hang in there anon
>>
bumperino
>>
What are some little tricks you guys use in eshell?
>>
>>110109068
I wrote a $ macro to make it easier to access Eshell variables from Elisp.
(defmacro $ (var)
"Shorthand for reading VAR using `eshell-get-variable'."
`(eshell-get-variable ,var))


I use it mostly in Eshell scripts that are dominated by Elisp code rather than the shell-like syntax.
>>
>>110109068
I came across a system for bookmarking directories for Bourne-compatible shells.
https://jeroenjanssens.com/navigate/

I initially discovered it through this blog post by an Emacs user who expanded it to work with eshell.
https://mbork.pl/2017-03-04_Bookmarking_directories_in_Eshell

Beyond the jump provided by the blog post above, I added eshell commands for mark, unmark, and marks (to list all the bookmarks).
(defun eshell/mark (mark)
"Mark the current directory with the name specified in MARK."
(let* ((mark-symlink (concat "~/.marks/" mark)))
(if (file-symlink-p mark-symlink)
(if (string= "Yes" (completing-read
(format "Replace existing bookmark to %s? "
(file-symlink-p mark-symlink))
'("Yes" "No")))
;;replace
(progn
(eshell/rm mark-symlink)
(eshell/ln "-s" (eshell/pwd) mark-symlink))
(message "Mark `%s' preserved." mark))
;; normal
(eshell/ln "-s" (eshell/pwd) (concat "~/.marks/" mark)))))

(defun eshell/unmark (mark)
"Remove an existing bookmark, MARK."
(let* ((mark-symlink (concat "~/.marks/" mark))
(target (file-symlink-p mark-symlink)))
(if target
(eshell/rm mark-symlink)
(message "Mark `%s' doesn't exist." mark))))

(defun eshell/marks ()
"List available eshell bookmarks."
(interactive)
(let* ((files (directory-files "~/.marks")))
(cl-loop for f in files
do (if-let* ((symlink (file-symlink-p (concat "~/.marks/" f))))
(eshell-print (format "%15s %s\n" f symlink))))))


I've also bound eshell/jump to a key.
  (define-key eshell-mode-map (kbd "C-]") #'eshell/jump)
>>
>>110109999
What I like about this system is that these bookmarks can be shared between Emacs and the shell.
>>
This is an interesting exercise in writing optimized CL code.
https://github.com/amno1/wordcount

He wrote a wc implementation that is on par with a fast wc implemented in C.
https://github.com/expr-fi/fastlwc/

He also did not drop down into assembly to achieve this. However, he did use processor-specific code in a pure Lisp context.
>>
>>110110435
can you use sbcl like a shared lib, lightweight binary or you need ECL for that?
>500 mb wc because you need to carry the entire thign with you
>>
just implemented a cool extension for EDN
>>110112096
>>
Anybody got any experience translating elisp to clisp? Thinking about swapping over to climacs if I can just autotranslate plugins.
>>
new Rich Hickey talk just dropped, he talks about the new destructuring capabilities in Clojure 1.13
https://www.youtube.com/watch?v=P5eO7BNyJao
>>
>>110112779
also, I think this video is a good representation of what it means when we say that Clojure is "data-oriented," and why I definitely prefer Clojure over everything else (including Common Lisp).
>>
>>110112789
I'd consider Clojure more seriously if it had mutability and wasn't tied to the JVM
>>
>>110112887
1. Clojure absolutely has mutability. you can use atoms for thread-safe mutation. you can use volatiles for thread-unsafe mutation. you can directly use ANY Java or Java-lib mutable datastructure by simply instantiating one and calling the methods of it.
2. ClojureCLR, ClojureScript, Jank (being worked on), and Babashka exist. otherwise, the JVM is really fucking good, if a bit bloated. I choose to not care about the bloat, and get shit done, which turns out to be incredibly simple when I can access literally any Java (or JavaScript, or Python via libpython-clj) lib in existence.
>>
Clojure has all the ideas I like but I used it a little and errors threw Java stack trace at me
I don't wanna learn java :(
>>
>>110113359
I don't understand why this meme refuses to die
You don't have to learn Java.
The errors are understandable.
user => (/ 1 0)
Execution error (ArithmeticException) at user/eval4649 (REPL:1).
Divide by zero
user => (conj 1 [])
Execution error (ClassCastException) at user/eval4651 (REPL:1).
class java.lang.Long cannot be cast to class clojure.lang.IPersistentCollection
>>110112887
The JVM is an absolutely GOATED platform
>>
>>110113359
scroll up the stack trace until you see `.clj` files
I actually find Clojure stack traces even easier to understand sometimes than Rust compilation errors, because there is not a ton of colored shit thrown at my eyeballs
>>
File: HUwNXJ_acAAVbUy.jpg (905 KB, 1440x1800)
905 KB JPG
https://x.com/MarcelDeneuve/status/2111078084946558979
>>
>>110113359
> java stack trace
> jvm
It was never viable from its inception.
yes, a lot of people use it, but there is a lot of inbreeders too. Doesn't mean it’s good.
Only stupid people adopted it, and, being stupid, developed things like spring.
>>
>>110117757
This jumble of classes and frameworks is one of the reasons Clojure exists to begin with. Just work with data and core Java and not this mess of pOOP
>>
>>110117757
The stairway to heaven
>>
>>110113420
You really need to know Java to understand most errors, even this one has a reference to a "java.lang.Long", whatever that is. I know Java and agree the JVM is goated.
I had a random long cannot be cast to something error, or vice versa, a long time ago, it was hard to track down because it wasn't at the top level in a repl (where all errors are trivial) but in some nested function call involving a lazy collection. Laziness is the biggest source of bug bears in the language, a true mistake inherited from flirting with Haskell.
>>
>>110119235
I think laziness is the biggest issue with Clojure. Beginners always get it wrong and it destroys stack traces.
I dealt with Python, Perl and Tcl stack traces before coming to Clojure and I must say it's infinitely better.
You don't have to know Java to know what a long is, you can figure out a java.lang.Long is probably a long. I wouldn't argue with the claim that since Clojure is a hosted language that embraces the platform, you should familiarize yourself with the platform, but ffs it takes about a couple of hours.
Lisp also has a laziness legacy (see Cons should not cons its arguments). It seemed like a good idea at the time.
>>
>>110112779
Rich Hickey-sama kakkoii
>>110112789
It's more "maps all the way down" than data oriented, which I decided I didn't like, as there are tradeoffs and these sorts of things (including spec) exist largely to alleviate some of the self-inflicted problems.
Like in Common Lisp, or most other languages, if we need something that's an address, we can just make an address object that contains the necessary fields. Two years later the business expands to shipping beyond the US to one extra country, so now we need to add some extra fields, at minimal a country, so we update our object and have to go audit things that used an address to determine whether they need to care about these new fields or not. It may even make sense to have a class hierarchy of different kinds of addresses, so now a function dealing with US addresses really doesn't need to deal with other countries. Same thing happens with maps, only it's harder to track down usages. Next, regardless of objects/maps, you'll need to update your database schema to handle the extra complexity as well, and update your front-ends to handle the new flows of dealing with a second country. It's all a lot of work, maps vs objects doesn't matter that much.
I still think his principles around trying to be flexible and not break others or be needlessly prohibitionist are sound regardless of the language.
>>
why is this thread just botposting now
>>
>>110119881
>Two years later the business expands to shipping beyond the US to one extra country, so now we need to add some extra fields, at minimal a country, so we update our object and have to go audit things that used an address to determine whether they need to care about these new fields or not.
you should have represented the address as `:some-namespace/address`, then it is easy to find all instances of use.
>It may even make sense to have a class hierarchy of different kinds of addresses, so now a function dealing with US addresses really doesn't need to deal with other countries.
add another key `:some-namespace/address-kind`. use Clojure's generics to deal with dispatching if applicable.
>Next, regardless of objects/maps, you'll need to update your database schema to handle the extra complexity as well
I agree that SQL databases tend to get "rid" of this no-classes approach by introducing tables/views, but also, the SQL algebra allows for trivial working with subsets/combinations of sets, which, at a high-level glance, seems similar to Clojure's destructuring. Postgres functions allow you to define custom return "tables" for the specific context of that function.
also, Datomic is an entirely different approach to the problem of databases in the same vein as Clojure's.
>>
>>110119987
Lisp is the original AI language
>>
>>110120889
>you should have represented the address as `:some-namespace/address`, then it is easy to find all instances of use.
>use Clojure's generics to deal with dispatching if applicable.
At this point you're mostly back to `defclass` and `defmethod`.
There is a whole separate approach here, context-oriented programming. In Lisp we have https://codeberg.org/pcostanza/contextl but I'm not aware of anyone actually using it. Still in theory it's attractive: if you suddenly need to support another country, you're going to have to update more than just address logic. Having that country live as its own context / layer name and being able to specify all sorts of classes or methods dealing with addresses, currencies, taxes, localizations, legal procedures, etc. clearly within specific layers sounds nice. Or even as just an alternative implementation of feature-flags or a context lookup singleton (stick conditional checks of `layer-active-p` in existing code as necessary).
>>
Reminder that dynamic typing is strictly inferior to static typing and, as a corollary, lisp is strictly inferior to statically typed languages. Imagine never being sure your code still makes sense after you move a bunch of functions around or you change the name of a variable. Imagine being afraid of having a typo in your code that could break your app at runtime. Imagine HAVING TO write tests for every function, for every combination of inputs to test all executions path because your inferior compiler doesn't do it for you. This is what lisp and scheme are.
>>
>>110120889
Fair point though that if you go all in on Clojure, something like :address/zip is the same name in the server Clojure, the client ClojureScript, the Datomic db, the wire format... whereas a CLOS accessor is only alive for the Lisp image. And this new approach Hickey is presenting is helpful at the boundaries between systems whether or not each system is part of the Clojure world.
>>110121434
Imagine being this retarded.
>>
>>110121486
>Imagine being this ret
In procedure raise-exception:
Unbound variable: retard
>>
>>110121526
* (compile nil (lambda () (format t "You are ~[super~;ultra~:;hyper~] retarded" level)))
; in: COMPILE ()
; (FORMAT T "You are ~[super~;ultra~:;hyper~] retarded" LEVEL)
;
; caught WARNING:
; undefined variable: COMMON-LISP-USER::LEVEL
;
; compilation unit finished
; Undefined variable:
; LEVEL
; caught 1 WARNING condition
>>
>>110121434
just use coalton if you can't help yourself from changing a variable's type.
>>
>>110121692
The whole ecosystem around that (common lisp) is dynamically typed garbage.
>>
repill me on clojure
>>
>>110121766
There's also typed racket. But you can see how much interactivity is sacrificed for better static guarantees here
>>110121434
I don't write tests separately. My programs grow from trying things out in the REPL and the result of this back and forth become the tests organically
>>
>>110121434
An anon explained it in the previous thread:

>>110046212
>The REAL advantage of dynamic typing is that it is a precondition for interactive development. An interactive development environment and static typing are almost mutually contradictory. Because if you redefine static types then the new definition has the possibility to collide or invalidate the currently compiled functions that are currently running.

There is a similar conflict between immutability and interactive development. Recall that in some languages you are not supposed to reassign variables too much; and yet, during interactive development, things get redefined all the time. Racket ran into some issues with this and provides enter! as an alternative to require when importing things in the REPL, since require only imports things once.

>tl;dr: It is really about what makes the most sense in an interactive context. Type hints are fine and can indeed make for faster compiled code, but they shouldn't get in the way of the interactive workflow.
>>
ocaml has a repl and interactive development and static types.good morning sirs!!!
>>
>>110122826
Can I build my program inside that REPL?
Can I change function definitions in my running program and the live program's behavior will change along with them?
The answer is obviously no. It's just a toy for tying things out. You'll end up building a static artifact using a different process (the compiler, not interpreter).
So you get a live script with type checking. fucking jshell does that now. yay.
>>
>>110122017
Though nobody ever talks about it, Prolog is probably the only language that's not a lisp or smalltalk with serious live programming facilities, and it also only has immutable variables.
Scheme in general has troubles with live programming because they lack images. Not being able to dump and load an arbitrary heap fucks the whole paradigm up.
>>
Bros, janet, chicken scheme, or gnu guile for embedding a lisp in my C program?
Plz don't ask me for more context or nuance, just share your favorite
>>
>>110122826
Many languages have REPLs, that is not the issue. The question is how static types, immutability etc. fit into the interactive development process. How strict should the interpreter be about enforcing them? Perhaps a lenient approach works better when the user is developing new code on the fly, or when changing existing code. This doesn't mean that the code cannot have types or const declarations, only that a modicum of flexibility on the part on the interpreter seems to be useful for interactive programming purposes.
>>
>>110123913
ECL
>>
>>110123913
Probably Janet because of the nicer standard library that comes with immutable data structures
>>
>>110123913
write your program in clisp and use sb-alien to call into C modules
>>
Emacs comes with a lot of color conversion functions, but it doesn't have a function that handles one of the most common color formats -- #000000. Here's something I wrote a while back to fix that.
(defun color-hex-to-rgb (color)
"Transform a hex encoded COLOR to individual RGB components."
(let* ((_ (string-match (rx "#"
(group (= 2 hex-digit))
(group (= 2 hex-digit))
(group (= 2 hex-digit)))
color))
(r (cl-parse-integer (match-string 1 color) :radix 16))
(g (cl-parse-integer (match-string 2 color) :radix 16))
(b (cl-parse-integer (match-string 3 color) :radix 16)))
(mapcar (lambda (n) (/ n 255.0)) `(,r ,g ,b))))


I want to be able to handle #000 also, but I didn't need it at the time, so I didn't bother.
>>
Is the best emacs terminal emulator still vterm?
>>
if the web was written in elisp, none of this would have happened
>>
>>110127785

you find emacs needs runlevel five
>>
>>110128337
no, it should have been written in fennel with open resty. high perf web
>>
>>110124046
Use case for having an inconsistent program? Why would you want to have a broken program, even if it allowed interactive development? Suppose you rename a function, or you turn an alist into a plist or hashtable, or you remove a field from a class for example: every other function using it is automatically broken and dynamic typing doesn't catch it, and you would have a broken program. Static typing would tell you exactly each function you have to change before making your change.
With dynamic typing, even with runtime errors, there's still a chance of missing some function.
Also, in principle, why couldn't you have a lisp-like repl with static types? Just imagine lisp but with they type system of ocaml or something like that.
>>
>>110127785
I'm mostly using ghostel nowadays. I know it's vibe coded slop, but it mostly works, and has comfy shortcuts. It works on windows too. Another nice one is eat. I don't like that vterm has only copy mode (instead of something like line mode) and that the mouse clicks (e g in htop for example) don't work out of the box.
>>
Schemathesis and hypothesis where perfect things for LISP, but alas they were made in python.
>>
>>110129444
>Also, in principle, why couldn't you have a lisp-like repl with static types? Just imagine lisp but with they type system of ocaml or something like that.
you can. Haskell has ghci, it works fine.
>>
>>110130595
Exactly. There's no actual advantage to dynamic typing.
>>
>>110129444
>every other function using it is automatically broken and dynamic typing doesn't catch it
If you didn't provide a migration strategy (why the fuck wouldn't you? some of these have default migration strategies btw) the program would just continue executing as normal until it hit a broken function, at which point the change is trivial. i don't think you really understand interactive development.
>Static typing would tell you exactly each function you have to change
except it wouldn't, because lisp is flexible enough that doing this requires solving the halting problem


>>110130595
ghci isn't really a lisp-like repl, and given the million quirks with deferred type errors, i have no idea why you would even posit it as a good example of static types in a repl. all of this besides the fact that the thesis was about interactive development and not just a random repl.
>>
>>110129444
The dichotomy between static and dynamic languages is a bit overblown. The question is really about what type errors mean, how serious they are, and how they should be handled.

Consider types in the context of compilation. When a compiler asks you what type a variable has, what it is really asking you is how many bytes of memory to reserve for that value. If the compiler gets that wrong, the output will be incorrect, and will probably crash if you attempt to run it. Therefore, a wrong type is, in this context, a serious error.

Now consider the task of interpreting the same program. In this case, a wrong type might actually not make that much of a practical difference, since what the interpreter does behind the scenes may very well be to instantiate some garbage-collected value, tag it with a type annotation, and let the garbage collector deal with the task of freeing it when it is no longer used. Therefore, a wrong type doesn't necessarily mean that the program will not run. Thus, what is an error to a compiler might just be a warning to an interpreter.

This suggests that in an interactive context, it might be useful to be able to run and repair an incorrect program while it is running, even if its types are wrong. That doesn't necessarily mean that you can't run it (even if it does mean that you probably shouldn't try to compile it).

What it comes down to is that adding type annotations to a dynamic language is easy, and has been done a number of times already. Making a static language more dynamic, on the other hand, is hard. These days, Java has 'var' and C++ has 'auto', but neither of them has something like TypeScript's 'any'. That is not to say that you should use 'any' all that much, only that it is a useful feature to have. Likewise, it is useful to be able to run a program in spite of type warnings, even if it goes without saying that you should deal with those warnings before committing any code.
>>
File: images (29).jpg (25 KB, 588x513)
25 KB JPG
I have much LISP knowledge
But nothing to build
>>
>>110132453
build fibers for common lisp
>>
>>110132373
>the program would just continue executing as normal until it hit a broken function, at which point the change is trivial.
It isn't guaranteed that you hit *all* the broken functions. You may miss some and find out only when the program breaks in production.
>except it wouldn't, because lisp is flexible enough that doing this requires solving the halting problem
This happens because lisp is dynamically typed though. Also if I remember correctly typescript type system is Turing complete too, but it still gives all the benefits of static typing.
>>
>>110133509
Common Lisp supports compile-time type checking.
>>
>>110133875
Would you say scheme is crap / pointless because of its lack of features such as this? Just curious.
>>
>>110134226
>he doesn't know that he can write macros that add a type system, if he feels they are actually needed
>>
>>110134226
Check out Typed Racket, anon.
BTC
bc1qtm4rep7kyp2p28hlkfktpnd0j7uew47vnt2mev
LTC
ltc1q9xlaysse0mpfwf025esd69kt9zu3md22gh23du
ETH
0x6abA18D203520c8F90ca63eE7426a7bC345D98e6
SOL
E5ekoiauCR8yiNp451dmuPzhUxo84P5x3m9WJBK5kxZe
XRP
r3jYXNdMk2Vz5hXhKCKE9re8uz93JQFG1r
DOGE
DSBq5jRWkiwmEh1G7zBwmQDgRkvRr61fmb
XMR
85CTwq5wGjWZw5GgzgwZPrHyZxpLXMK5oZSSSk5j4x9w1bpqzisaWAUZYaAPfh6rP2MZJcaFqF1XmEzkw6YCqJSS2Txu6Z8




Delete Post: [File Only] Style:
[Disable Mobile View / Use Desktop Site]

[Enable Mobile View / Use Mobile Site]

All trademarks and copyrights on this page are owned by their respective parties. Images uploaded are the responsibility of the Poster. Comments are owned by the Poster.