beneroth changed the topic of #picolisp to: PicoLisp language | The scalpel of software development | Channel Log: https://libera.irclog.whitequark.org/picolisp | Check www.picolisp.com for more information
<aw-> PicoLisp is still my favorite language in 2025. ^5 abu[7] thanks again for your creation.
<beneroth> mine too! so grateful for your work and that you made it available <3
<aw-> beneroth: ^5
ygrek has quit [Remote host closed the connection]
<abu[7]> Thanks aw-! I'm happy to hear that!
geri has quit [Remote host closed the connection]
geri has joined #picolisp
<geri> hey, happy new year with 2 day delay :D
<geri> and question already - what can you do with fexprs that you cant do with macros?
<geri> can already guess - not evaluate things :D
<abu[7]> You can't single-step a macro
<geri> you could single-step its resulting code, if it returns a valid list anyway
<abu[7]> Yes, but that's not the macro any more
<abu[7]> All debuggig
<abu[7]> pp
<abu[7]> You lost the original
<geri> okay fair
<geri> mapping and is uglier but you can just do (map[car?] (lambda (x y) (and x y)) list1 list2)
<geri> i think
<abu[7]> What has this to do with FEXPRs?
<geri> the fact in picolisp you can (mapcar and '(T NIL T) '(NIL T T))
<geri> yeah lambda option works in chez
<geri> uniformity of fexprs is way nicer than normal functions, special forms and macros
<abu[7]> 'and' is not a FEXPR
<abu[7]> it is an FSUBR
<abu[7]> (but a SUBR on the Lisp level)
<abu[7]> (Pil has no SUBRs internally)
<geri> it doesnt change the meaning dramatically
<abu[7]> T
<geri> you can implement and with a loop and ifs and it'd function the same way (which is cool)
<abu[7]> But you can apply or map 'and' because it is evaluating all args (though not necessaraly all)
<beneroth> geri, a FEXPR can evaluate differently based on input. that input could be from a user or imported file (e.g. when implementing a parser as FEXPR).
<beneroth> a macro needs to know all behaviours at compilation time, a FEXPR only at runtime
<abu[7]> good point
<beneroth> compiled lisps can only solve this by including a lisp runtime in the final executable
<beneroth> some FEXPR can be compiled, but not all of them. if a FEXPR's evaluation depends on data/arguments received during runtime, it cannot be compiled as at compile time the necessary information is not available
<geri> beneroth: you can switch based on value of symbol on runtime, athough also ugly
<beneroth> of course this could be solved by generating all possible FEXPR runtime variants during compile time (maybe a bit like how templates work in C++), but as the number of variants might potentially be huge, you end up just adding again a runtime interpreter into the executable (in the best case)
<geri> xd
<beneroth> geri, check out @lib/xhtml.l - the (de tag ...) function is an FEXPR. The content of the html element it receives as unevaluated Prg
<beneroth> geri, switching based on value of symbol works only if you know all possible values for that symbol during compile time. but it might be lisp code based on an input file or network input your programm received - e.g. to implement a user scripting language
<beneroth> FEXPR are really useful to implement DLSs (domain specific language)
<beneroth> s/DLS/DSL
<geri> you cant switch in fexpr without knowing what you wanna switch on either
<beneroth> well you don't switch, you evaluate
<geri> so if you want path to be a transient symbol or a value, you need cases in the body to handle the cases
<beneroth> what if path is a function calculation the resulting value based on many factors (time of day, geographic area, ...)
<beneroth> of course there are ways... as long it is turing complete, it can always be done. but with FEXPR you can delay and separate runtime behavior while in compiled languages you need it all at compile time or earlier
<beneroth> so it's a huge difference on how to organize and plan the work, and how easy you can change it
<geri> what i meant with switching is basically your behaviour is a normal function that gets called on runtime and macro is just there to force non-evaluation of arguments
<geri> pass arguments to evaluating function and you got same behaviour, although ugly
<beneroth> the compiled way might have benefits for lazy workers, as you can spend more time taking breaks while waiting for compilation to finish (or choke on a small mistake after 30min).
<geri> xd
<beneroth> arguably with picolisp you might be finished earlier and can take the rest of the day off, so there's that :)
<geri> :DD
<beneroth> which also makes picolisp bad for bigcorp, because there you as an employee are paid for your presence time, rarely for your results
<geri> honestly facts
<beneroth> and in reverse picolisp is benefical for independent programmers with their own projects (or even business) valueing results only
<beneroth> and surprisingly this is kinda the kind of people we see here :)
<geri> im an independant script kiddie
<beneroth> picolisp is also bad for bigcorp because it gives more control to programmer but also requires better programmers than Java/C#/python, and bigcorp like their programmers to be interchangeable serfs
<beneroth> geri, we all are xD
<geri> )
<geri> even with python there are good programmers and bad ones
bjorkintosh has quit [Quit: "Every day, computers are making people easier to use." David Temkin]
<geri> although getting some use out of python with a bad programmer is easier than with lisps
<beneroth> yeah, that's my argument
<beneroth> good/bad programmers you find in every environment
<beneroth> but java/c#/python have guard rails which kinda produces a floor of minimum productivity even if you just try random things
<geri> python probably less so than others
bjorkintosh has joined #picolisp
bjorkintosh has joined #picolisp
<geri> exploses a bunch of stuff other languages dont
<geri> single expression lambda is so bad though
<beneroth> the disadvantage of such guardrails is that it usually hinders very good programmers in their productivity (I'm sure about that in java and c#, I don't have enough python experience myself to say about python). With picolisp, the upper limit of productivity is much higher for a capable programmer.
<geri> imo thats true for pretty much any lisp
<geri> some people swear by forth as well, but it hadnt clicked for me
<beneroth> well C# has a pseudo-lambda in it (LINQ) which can be used to either represent in-memory data processing or SQL queries, but depending on in which context they run you cannot use the same features. bad magic.
<geri> sql queries are built into the language's lambdas??
<beneroth> geri, picolisp is actually influenced by forth. abu[7] attempted a forth language too. But with forth a lot of context has to be held in the programmers mind, the lisp approach worked better.
<geri> yeah
<beneroth> geri, in C# a kind of lambdas can be compiled into SQL queries
<beneroth> but yeah, it's kinda fucked up
<beneroth> an attempt to copy lisp features without becoming lisp
<geri> just become lisp and become a better language honestly
<geri> remove fancy frontends and most languages are seldom different from lisp
<geri> high level ones i mean
<beneroth> resulting in C# being now a mess of a language, not like C++ which is overly broad, but in C# it's like multiple context-specific languages looking the same when they are not. which kinda makes C# programming infeasible without an IDE which gives a lot of context and auto-completion.
<beneroth> no no no, you cannot become lisp. scary parenthesis!! (though most lisp have arguably the same number or even less than C-langs, but C-langs use different type brackets)
<geri> afaik java is rather unusable without ide too
<beneroth> the point of java and c# is not a better language, but a widely used language under corporate control
<beneroth> yeah
<beneroth> xD yeah javascript is arguably the worst
<beneroth> well if the syntax doesn't change every year, how you sell new trainings and new certifications of developers to bigcorps?
<geri> thats so stupid
<geri> to be fair, i do understand constant change in programming languages now
<geri> cause i myself constantly find ways to improve things, often breaking compatability
<beneroth> USA really didn't simplify their tax code a few years ago because the tax accountants heavily lobbied against it
<beneroth> if it would become to simple, many people could do their taxes themselves...
<geri> ~w~
<beneroth> geri, I think well designed languages should not need many changes, after an initial phase
<beneroth> because new features should be library extensions and not language changes
<geri> im not exactly talking about pl implementations but code in general
<beneroth> the underyling computation model hasn't changed a lot in recent decades, I'd argue
<geri> and programming languages are code themselves
<beneroth> yeah code in general and specific applications is another topic
<beneroth> huge part of it is also how you improve. if you don't find some of your code from 6 months ago bad, than you probably didn't improve
<beneroth> I don't think programming languages are code. The implementation (interpreter or compiler) is code, but not the language concepts and syntax
<beneroth> a programming language is a set of rules and concepts which can be represented in code, but are not code themselves
<bjorkintosh> beneroth: are you conflating algorithms with programming languages?
<beneroth> with business applications you have the business processes and way of working, which change a lot all the time (new company activity, new laws, ...). that's why there must also be constant application changes.
<beneroth> but in computing.. the essence isn't changing so much, changes happen over decades not months or weeks.
<beneroth> bjorkintosh, I'm not
<bjorkintosh> ah okay.
<bjorkintosh> It just sounded a hell of a lot like that.
<bjorkintosh> My mistake.
<beneroth> np
<geri> reminds me about constant changes in firefox ui
<geri> one of the older ones was the best looking
<beneroth> I would say a programming language can be viewed as a set of algorithms, turning source code into byte/bit patterns
<geri> shouldve worked on proper features instead
<beneroth> (well source code and input)
<beneroth> geri, yeah. well. firefox is just a lame excuse for Google that Chrome is not viewed as monopoly. and for Mozilla executives to become rich.
<geri> eh
<geri> still better than chrome
<beneroth> geri, btw FYI the status of clojure being a lisp or not is still up to debate, the smug lisp weenies say
<beneroth> arrogant assholes :)
<geri> do you know janet
<beneroth> no. a person? a language? sister of julia or what?
<geri> language
<geri> its got sexps & macros, first class functions etc.
<geri> but it uses arrays for AST
<geri> *is it a lisp?*
<bjorkintosh> geri: have you used it?
<geri> a bit
<bjorkintosh> what say you?
<geri> imo "being a lisp" is more about the spirit than particular components
<geri> and janet has lispy vibes
<geri> some argue scheme isnt a lisp
<bjorkintosh> something being or not being a lisp shouldn't really matter though.
<geri> yeah i dont think it does
<bjorkintosh> I'm more interested in how deep into the turing tarpit a language is.
<beneroth> I think the essence of lisp is "code is data"
<beneroth> which clojure doesn't really fulfill
<bjorkintosh> beneroth: yes that's all good too. it's just one more path to implementing an algorithm.
<beneroth> T
<geri> bjorkintosh: is it about brainfuck basically
<beneroth> it's a question of viewpoint and taste, as I don't think there is a definitive authoritative definition
<geri> technically turning complete, practically you cant write anything useful in it
<beneroth> clojure is clearly a lisp syntax-wise
<bjorkintosh> geri: yes. and other such languages.
<bjorkintosh> also, sometimes I find that common lisp libraries haven't been breathed on since the early '90s.
<bjorkintosh> that's another sort of turing tarpit.
<beneroth> javascript is clearly not a lisp syntax-wise, but then the internal model is very lispy, just based on objects instead of S-EXPRs
<bjorkintosh> dictionaries, beneroth.
<bjorkintosh> key/value pairs.
<beneroth> functions are objects with properties, technically
<beneroth> bjorkintosh, I never did any common lisp. I came to lisp from C/C++, saw that common lisp has a lot of compiler-specific stuff and a lot platform-dependent stuff, so I was like "hell nah, had enough of that with C/C++"
<geri> xd
<geri> you dont have to use it
<geri> although its helpful for performance
<beneroth> no, but I have to learn which parts are independent and which have which dependances
<geri> you do in any language
<bjorkintosh> functions are tables, beneroth.
<beneroth> I mean, the core language of C (and most of C++) is the most platform-independent stuff there is, but as soon as you bring libraries into play it's a complete different game
<geri> maps input value to output value :)
<beneroth> xD
<beneroth> it's only true in one direction
<beneroth> pi is a function. but there is no complete table for it. in all likelihood, the universe implements PI also as a function and not as a value.
<bjorkintosh> functions<->maps<->tables<-dictionaries-><-associated-arrays-> All look same.
<beneroth> yeah but differently structured in memory
<beneroth> and the differences matter in some use cases
<beneroth> information can be transformed and represented in different structures and formats
<beneroth> the information itself doesn't change because of it
<beneroth> (well some formats might be lossy compressions, so then there is an information change)
<bjorkintosh> beneroth: what is memory? yet another table where each cell is an address and the contents at that address.
<abu[7]> For me Lisp is all about 'cons'. Thus Clojure is not a Lisp.
<abu[7]> Lists and symbols
<beneroth> bjorkintosh, I believe the memory in your brain is quite differently structured
<bjorkintosh> beneroth: naturally. different species.
<beneroth> abu[7], also a good point. and tightly related to the "code is data"
<abu[7]> T
<abu[7]> Java is a poor implementation language for Lisp (though I used it for ErsatzLisp), because it has no pointers, and a cell has huge overhead as an object
<abu[7]> Thus Closure has no 'cons' (linked list) and does it all in arrays
<abu[7]> This is much less flexible than Lisp, needing a complete new array for a cons, but they sell it euphemistically as "immutability" :)
<geri> abu[7]: but if you got janet you can add cons cells with arrays of 2 items
<geri> so lists are back and now its a lisp? xd
<geri> code is data can be done with arrays, just not as efficient to edit beneroth
<abu[7]> Not sure if that suffices
<abu[7]> I just said what is not a Lisp
<geri> idk
<geri> imo "code is data" is a core feature as well, but you can implement it differently
ygrek has joined #picolisp
<abu[7]> Frau some people it is enough if you have parantheses and prefix notation
<geri> technically macros do that, you can have lists be arrays instead etc.
<geri> abu[7]: yeah, honestly not for me, there's cmera and such which are just sexp wrappers over C
<geri> with lisp style macros
<abu[7]> T
<abu[7]> or NewLisp
<beneroth> any opinions on arc, anybody ever used it?
<abu[7]> not really
<geri> what about newlisp abu[7]
<abu[7]> It does not even have a garbage collector
<abu[7]> The power of Lisp is that your data are arbitrary graphs
<geri> do you really need gc for it to be a lisp
<geri> XD
<geri> naming stuff is diffuclt
<abu[7]> NewLisp allows only a single reference
<abu[7]> Ref Count
<abu[7]> Without gc you lose almost all power and flexibility of a Lisp
<geri> i honestly only know about newlisp that it has fexps for macros
<abu[7]> With single reference you can't have circular structures
<abu[7]> And in Lisp *all* is circular
<abu[7]> Symbols have data which point to other symbols ultimatively to namespaces in turn holding all symbols
<abu[7]> Can't be done with a ref count and withot gc
<geri> abu[7]: circular to be sounds like circ, not like trees
<abu[7]> I mean not plain circular lists (1 2 3 .)
<abu[7]> Circular references between data in general
<abu[7]> Only a gc can handle this
<geri> ah yeah
<abu[7]> Otherwise you get lots of memory leaks
<geri> reference counting cant do self references
<abu[7]> right
<abu[7]> or circular in general
<geri> a -> b -> c -> a
<abu[7]> : (get 'car '*Dbg)
<abu[7]> -> ((17 "@src/subr.l" llvm pico))
<abu[7]> And 'pico' has 'car
<abu[7]> So circularities everywhere
<beneroth> T
<beneroth> so it's kinda like doing C/C++ and working exclusively with stack variables
<beneroth> sounds like a lame excuse to not implement a gc
<abu[7]> They claim it is faster this way, but I can't beleive. Needs so much bookkeepinp and copying.
<beneroth> yeah I agree. The bookkeeping is of course implicit, so needs no extra effort in the implementation, but costs during runtime. And the copying must cost a lot too, only really feasible with much RAM and good CPU caching.
<beneroth> it's probably "good enough", but well, that is a low barrier and the reason why today's software is so much worse and more bloated than in the past - in the past we couldn't afford such waste
<beneroth> all that waste costs energy, that should be kept in mind. energy which can be used for something else and which probably has additional costs in pollution or climate change attached to it.
ygrek has quit [Remote host closed the connection]