libera/#lisp - IRC Chatlog
Search
17:17:29
ieure
Clojure is a good dialect for that sort of thing; Racket may also be worth looking at.
17:17:51
mihaiadrian
i only know a bit of bash, did some cpp in highschool, can understand and write js/python but don't like those two at all
17:18:16
aeth
mihaiadrian: for that you probably want libraries, so Common Lisp, one of the big three Scheme languages (Guile, Chicken, Racket), or I guess Clojure but I can't speak for it since I've never used it
17:18:35
aeth
note that each Scheme is its own ecosystem so they might as well be their own languages as far as this is concerned
17:19:17
Mrtn[m]
Did anyone actually make a study to find out if *common* LISP is the most /common/ LISP?
17:19:22
mihaiadrian
clojure runs on java and it's going to consume more server resources. and it's more difficult i guess, and calling those java methods kinda breaks the lisp workflow, right?
17:19:27
aeth
ieure: Common Lisp has the ugliest parts (e.g. RPLACA) because it didn't break backwards compatibility with 1960s Lisps, but it's also the only one that's not opinionated, either.
17:19:31
ieure
I like Clojure; it's the least impractical Lisp I've used. Use whatever Java libs you want, deploy on the JVM.
17:19:58
mihaiadrian
ieure: it's not that i don't like it, but i just prefer bash, as it seems more higher level
17:21:12
aeth
Each ecosystem has its own issues... most Schemes seem to be stuck in the early 1990s use-linked-lists-for-everything attitude, while the typical Common Lisp library has globals, globals everywhere.
17:21:20
ieure
To each their own, of course. Just that if you don't like Python, and you didn't like bits of it that were robbed from Lisp, there's a good chance you wouldn't like Lisp either.
17:22:18
aeth
ieure: ime, Scheme ruined my ability to enjoy Python because Scheme has a lot of easy-to-do functional programming that in Python, the BFDL didn't want you to be able to do easily, if at all
17:22:21
mihaiadrian
the syntax is a bit quirky, maybe there are better languages, but it's that utility -flag "parameter" thing that i like
17:22:33
aeth
Until I learned Scheme, I could port pretty much any concept I liked into Python and it would look better.
17:23:12
ieure
mihaiadrian, -option "arg" is a degenerate version of Python kwargs, which is a degenerate version of Lisp &key args.
17:24:12
ieure
Anyhow, sounds like you have some good recommendations, definitely pop in if you have more questions when you start picking one up.
17:24:59
ieure
I just started a job doing Clojure hacking, super grateful for that. Would love a CL job, but there seem to be very few. There were a surprising number of companies using Clojure when I went looking earlier this summer.
17:26:53
Mrtn[m]
Move to Bulgaria, if you can master the language. They live next door, and have lots of hackers from what I'm told.
17:27:09
ieure
mihaiadrian, I don't know if one is faster than the other, both Racket and CL compile to machine code. I wouldn't expect a major difference.
17:27:11
aeth
mihaiadrian: SBCL is probably the fastest Lisp out there, with the caveat that Schemers tend to craft comparative benchmarks in their favor (no type annotations) while fast SBCL requires type declarations which makes it more gradually typed than dynamically typed. (Fast Scheme, by contrast, gives up polymorphism and has you use stuff like fp+ or whatever instead of +)
17:27:34
mihaiadrian
bulgarians speak a slavic lang and they still use the cyrilic alphabet. we speak a latin language. the difference is pretty huge.
17:28:12
aeth
ieure: The difference is in focus, really. There are some fast Schemes and there are some popular Schemes, but the intersection isn't really there because portable Scheme is rare.
17:28:23
aeth
ieure: Whereas in CL, a lot of people use SBCL because it's fast and most libraries are portable.
17:28:57
aeth
Which probably gives them faster functional programming support because it can be built in
17:29:06
Mrtn[m]
mihaiadrian: Romanian has a slavic ring to it in some dialects, but it is basically a very latin language. I don't know if there are jobs in Italy, but that language should be easy on you to learn.
17:29:26
ieure
I've barely used Scheme, it has some good ideas, but I prefer the CL style in general.
17:29:59
Mrtn[m]
(Just pretend that they all speak Italian, and don't have 100's of dialects that are very different from standard Italian ...)
17:31:56
mihaiadrian
Mrtn[m]: yes, romanian and italian are somehow mutually inteligible. but i don't plan to relocate or find a dev job as i work in internet marketing and earn more than the average salary in my city. but i wouldn't say no to a lisp gig, if i end up liking the language. so far, i do.
17:32:33
aeth
Mrtn[m]: Personally, I'd say that there isn't really a CL style. The formatting of the code is incredibly consistent, but beyond that anything goes. That's probably why there's such an emphasis on having the code formatting look so uniform.
17:32:59
aeth
Heck, the library system ASDF is written in its own style that I've never encountered anywhere outside of ASDF
17:33:42
Mrtn[m]
aeth: I don't know how to format my common lisp to be honest .. I just go with <tab> .. but how to split the lines can be a hard choice sometimes.
17:34:48
mihaiadrian
i've downloaded portacle which is an emacs distro for lisp as well. just wasn't sure which one to start with.
17:35:33
aeth
mihaiadrian: A Scheme classic that's far more academic than those two is https://sarabander.github.io/sicp/
17:35:47
dmrz
does anyone think that representing code as linked lists rather than just arrays is a really good feature that next-generation lisps should keep?
17:36:47
aeth
mihaiadrian: My personal favorite Scheme book (with its own, radically different style, more of a series of code puzzles) is The Little Schemer, but that's not (legally) free online. https://mitpress.mit.edu/9780262560993/the-little-schemer/
17:37:22
aeth
There are a bunch of sequels to it, too, but I don't see the point. You don't have to even get through the whole first book before you "get" Scheme
17:38:33
aeth
There are some other Common Lisp books beyond PCL, of varying quality. Usually old because authors tend to prefer to write about Scheme these days. https://www.cliki.net/book
17:40:51
aeth
I can't recommend any Clojure books/resources because I don't know Clojure, but there are a lot of them out there.
17:42:04
mihaiadrian
i've looked at most of them and did some basic tutorials to see what they're all about, but really didn't know which one to go for
17:42:13
aeth
Oh, one more thing... The SICP lectures are available for free on YouTube in one giant playlist with videos of the lowest possible video quality imaginable. But the lectures themselves are good. https://www.youtube.com/playlist?list=PLE18841CABEA24090
17:45:25
Mrtn[m]
Unless you're an experienced LISP coder, you will most likely benefit, and maybe even then.
17:51:02
Mrtn[m]
So, sure there are differences, but programmers are used to that. Even in the same language, when you have to use a new Library, you have to learn how to work with that most effectively.
17:52:01
aeth
Emacs Lisp is basically just a worse/slower version of Common Lisp. Almost interchangeable.
17:52:21
aeth
Scheme is usually extremely similar to a subset of Common Lisp, just with almost everything renamed. Almost everything.
17:52:58
aeth
The main difference that produces a very different style between the two is that Scheme heavily relies on tail recursion because it's guaranteed, while in Common Lisp, it's an optimization.
17:53:19
aeth
There's also the "Lisp-1" vs "Lisp-2" thing. Scheme has a unified namespace (like most programming languages), while Common Lisp puts functions in its own namespace.
17:54:31
aeth
It's "map" in Scheme vs "mapcar" in CL because Scheme renamed everything (but Common Lisp uses MAP for the sequence-generic version)
17:55:06
aeth
it also means that in higher-order-functions where the function is passed in as a variable, you can do (f 42) in Scheme while you have to do (funcall f 42) in Common Lisp
17:55:46
aeth
Advantage in CL: You can use better names without accidentally/intentionally locally overriding the name for a useful function (you can just call a list a list while Scheme might have to call it l or lst)
17:57:19
aeth
in case you missed anything if you disconnected. https://irclog.tymoon.eu/libera/%23lisp?around=1663955510#1663955510
17:57:40
hodapp
was I also seeing properly that most libraries are for particular Scheme implementations rather than for Scheme itself?
17:57:46
aeth
in case you missed anything if you disconnected. https://irclog.tymoon.eu/libera/%23lisp?around=1663955510#1663955510
17:57:55
mihaiadrian
i was gonna say i'm not that good with emacs yet. but i do plan on learning it.
17:58:23
Mrtn[m]
mihaiadrian: You want to check that log, he basically explained a lot of basics about lisp variants.
17:58:30
aeth
hodapp: Yeah, Scheme itself is fragmented and that's problematic for Scheme. However, it's only a Scheme issue. Fragmentation between Lisps isn't an issue because you wouldn't expect C# code to run on Java or vice versa because they're very similar languages, not the same language.
17:58:48
hodapp
aeth: I was asking particularly with Scheme because it looked like Common Lisp didn't have this issue
17:59:32
aeth
and the large standards (R6RS, R7RS-large) are too large and potentially incompatible with the existing Guile/Racket/Chicken solutions
17:59:40
Mrtn[m]
hodapp: The next version of the standard is not finnished yet, and people struggle to agree on it.
17:59:49
aeth
hodapp: right, when you don't even have a define-library or whatever, then it's kind of hard to have portable libraries
18:00:23
aeth
(it's a weird Scheme-ism to actually refer to their meaningful libraries with names like (srfi 125) instead of something meaningful)
18:00:29
Mrtn[m]
aeth: I think Racket doesn't technically identify as a scheme anymore, for that reason (amoung other stuff possibly).
18:01:55
aeth
Mrtn[m]: Racket changed its name from PLT Scheme partially for branding and partially because it doesn't conform to the standard anymore because it breaks the basic s-expression/list assumption because cons pairs are immutable in Racket and you use an mpair for cons pairs that work like any other Scheme (or like Common Lisp or Emacs Lisp).
18:02:26
aeth
Scheme's already more of a language (sub)family than a language, and Racket takes that the furthest
18:03:27
aeth
hodapp: define-library is r7rs, but it's far too late to avoid fragmentation because most Schemes are r5rs and might have even started as r4rs
18:03:52
pjb
The problem with scheme is indeed, that you have to choose between so many different versions!
18:04:10
aeth
hodapp: Common Lisp also lacks something like this, but every noncommercial implementation of CL standardized on a library, asdf:defsystem
18:04:33
pjb
rs, r1rs, r2rs, r3rs, r4rs, r5rs, r6rs, r7rs? And next r8rs, etc it's endless, like python or unicode.
18:04:59
aeth
pjb: In practice, Schemes are r5rs, r6rs, r7rs, or "Scheme-like, but not standard at all"
18:05:17
aeth
The issue being that r6rs is so different from (and much larger than) r5rs that it basically split Schemes into r6rs and r5rs
18:05:27
aeth
with r7rs-small kind of reverting to r5rs (which is unpopular for the ones that went with r6rs)
18:07:04
aeth
Also note that most r6rs claim something like "99% compatibility" rather than complete compatibility. Because it made some unpopular, very-specific choices.
18:08:42
aeth
really depends on what you want... if you want higher-order-function-filled, recursive, dynamically typed, functional programming with a strong emphasis on doing it yourself from a minimal core and being tied to a specific implementation, then Scheme's still the way to go.
18:09:34
aeth
the second you use recursion all over the place in CL, you're writing non-portable CL, anyway
18:11:11
aeth
Scheme guarantees tail recursion; Common Lisp views it as an optimization that implementations are free to optimize or not (which might even change at optimization levels, e.g. (debug 3))
18:11:53
hodapp
aeth: oh, I wasn't taking 'recursion all over the place' as meaning tail calls, just as meaning frequent use of recursion
18:13:55
aeth
Common Lispers use LOOP, and if they don't they might use something like DO. Technically, DO is in both languages, but DO is implemented in terms of TAGBODY+GO (contained gotos) in Common Lisp and in terms of recursion in Scheme.
18:15:17
aeth
(mapcar #'funcall (do ((i 0 (+ 1 i)) (l '() (cons (lambda () i) l))) ((>= i 10) l))) => (10 10 10 10 10 10 10 10 10 10)
18:15:55
aeth
(map (lambda (x) (x)) (do ((i 0 (+ 1 i)) (l '() (cons (lambda () i) l))) ((>= i 10) l))) => (9 8 7 6 5 4 3 2 1 0)
18:16:39
aeth
technically, you can use (lambda (x) (x)) in the Common Lisp version, too, so the only difference that has to exist between the two is mapcar/map
18:24:11
dmrz
(trying again) if i were making a new lisp in which `(def x 8)` was a 3-elt array, not a linked list, does anyone think this is a really stupid idea that I should reconsider?
18:29:22
dmrz
so on the one hand, i've heard this suggested before, and not making macros suck is a very core design consideration so i want to make sure i'm not ignoring anything related to this
18:30:44
dmrz
on the other hand, are you sure it's actually harder, as opposed to just less efficient for the machine given common patterns of macro design?
18:31:52
dmrz
like, i know that a lot of forms are naturally processed as like: step 1: dispatch on (car s) to decide what to do with (cdr s), repeat
18:32:37
dmrz
and it's obviously somewhat more cumbersome to do this with something that doesn't naturally split into a car & cdr
18:33:21
dmrz
but this could easily be hidden from the programmer if you didn't think spending a few more instructions per macro evaluation step was a big deal (and i don't)
18:34:19
aeth
Afaik, you can fake car/cdr. #(1 2 3) can be decomposed into 1 and #(2 3) without allocating a new #(2 3) if the language is designed for that. So the problem would be arbitrarily inserting potentially long things in the middle.
18:34:50
aeth
That and you'd mutate a lot while most macros are purely functional even though the cons pairs are usually mutable.
18:36:04
dmrz
the arrays don't have to be raw arrays, they can be those things like rope strings but for arrays (not sure what the official name is)
18:38:52
dmrz
anyway, imo macros are only supposed to be purely functional in terms of their outward effects (i'm turning one tree into a different tree), not in terms of what they do to the machine
18:47:00
dmrz
Mrtn[m]: it's not supposed to be a simple or just-an-experiment language. basically, i'm taking a clojure-like route and writing a compiler
18:51:30
Mrtn[m]
If you're going to use the power of CL however, you might be better off writing it in CL.
18:53:29
dmrz
the implementation target is pretty much settled, at least for now; the main thing i want feedback on is the language design
19:18:46
jcowan
aeth and others: you only have to use "lst" if you are going to use the "list" function in the same lexical scope. I don't use the "list" function much, so I am happy to use "list" as a local variable.
19:21:00
aeth
funcall seems to only be useful in Scheme for the very specific purpose of calling a list (or other sequence) of closures in a higher order function, which seems very niche
19:21:38
jcowan
thirdly, you could unify lists and vectors by setting things up so that (car v) returns the first element of vector v, whereas (cdr v) returns a subvector of v starting at element 1
20:35:06
moon-child
jcowan: I don't see why funcall is useful for adapting cl programs to scheme. The primary hurdle is colliding names that were previously in different namespaces; once you've taken care of that, you can freely remove all instances of funcall
20:35:29
moon-child
but, as aeth points out, it _can_ be useful in scheme when writing higher-order functions
20:36:08
jcowan
You can freely remove them, but if you'd rather not mess with the source more than absolutely necessary, having a definition of funcall is a small step in that direction.
20:39:28
moon-child
my point is that ensuring there are no collisions is a very invasive change, far more so than removing instances of funcall
20:44:18
moon-child
(looked at my old code where I thought I was using it, but I guess I decided against using it, so I don't have an example, unfortunately)
21:43:38
jcowan
moon-child: I mean, what is the advantage of funcall when dealing with higher-order functions?
21:47:58
aeth
(define (funcall fn . args) (apply fn args)) (define mapcar map) (mapcar funcall (do ((i 0 (+ 1 i)) (l '() (cons (lambda () i) l))) ((>= i 10) l)))
21:50:25
pjb
jcowan: the advantage is that you can have both functions and variables named with the same name, just like in English and a lot of other natural languages.
21:50:26
aeth
You might think to do (defconstant funcall 'funcall) in the CL version because 'funcall works just as well as #'funcall, but, no, there's a package lock on COMMON-LISP (and thus on COMMON-LISP:FUNCALL) in SBCL and any other implementation is free to do the same.
21:54:20
aeth
pjb: Yes, it's a debate as old as time. Which one do you want to be easy and which one do you want to be awkward? (defun list-of-list (list) (list list)) vs (define (f x) (x))
21:58:50
moon-child
jcowan: you can pass funcall as the 'function' and some other function as the 'data' into a higher-order function to make the hof call the 'data' function
22:03:43
aeth
(define (funcall fn . args) (apply fn args)) (map funcall (list (lambda () 1) (lambda () 2))) ; works