IRC channel logs

2026-02-17.log

back to list of logs

<lechner>Hi, this does not work from compiled files. It should re-export bindings from machine-specific file. Do I need more eval-whens, please? https://bpa.st/WZPA
<jab>hmm, so apparently I can learn about bit more about functional programming. Apparently function programming uses closures, which I really haven't dabbled in. And it uses monads, which I still struggle to understand that concept. :)
<identity>jab: the conventional wisdom seems to be «understanding monads takes 3 tutorials and actually writing something with them»
<rlb>(you may also encounter them a good bit less in the "lisps")
<identity>it depends on where you look. dynamic typing eliminates some common uses of monads, though
<jab>takes 3 tutorials! haha.
<lechner>jab / the key to understanding monads lies in continuation-style programming or CPS
<jab>dynamic typing means that you only know the type of a variable when you look at it. A variables type can change during program execution. rightish ?
<jab>may I ask why lisp
<jab>like languages don't encourage pure functional programming? Why does scheme provide set! ?
<rlb>I'd probably lean toward becoming comfortable with closures and/or persistent data structures first wrt more "pure" functional programming.
<lechner>pure is not good
<rlb>And right, most lisps are hybrids.
<jab>why is pure not good (or not ideal) ? Why is a hybrid style better?
<rlb>though clojure leans a bit more toward functional by default -- i.e. all the normal data structures are persistent and mutation is strongly segregated...
<lechner>jab / it's very hard to create useful programs, i.e. programs with effects https://www.youtube.com/watch?v=iSmkqocn0oQ
<jab>thanks for the link
<lechner>in fact, it requires monads
<identity>jab: «dynamic typing means…» not exactly. dynamic typing means that the type of value is determined dynamically (usually meaning at run time) instead of statically (usually at compile time). in Scheme, variables can hold a value of any type, and the type is associated with the value, not the variable.
<lechner>identity's point being, I think, that Guile is strongly typed, but dynamically and not statically
<identity>lechner: «very hard» makes it sound like PFP is esoteric programming
<lechner>it is for me
<identity>lechner: yes, but also that it is latently typed (values have types, not variables)
<lechner>ok, but that's nitty-gritty for a novice
<jab>identity: yes, values have types. in that add can be a variable for a function.
<jab>or a function*
<jab>and during program execution "add" can change from a function to a variable.
<jab>perhaps I'm rambling a bit, but I've always wanted to give deeper into functional programming, and this is just super interesting.
<mwette>i like this for monads: http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html
<jab>I'll take a look! thanks!
<jab>so is scheme programming language nirvana ?
<lechner>no, it is street smart
<lechner>we are the alley cats of functional programming
<lechner>ocaml or haskell is nirvana. not sure which
<singpolyma>SML 😉
<jab>lechner in the youtube video that you linked, haskel was not programming nirvana. It was in the useless camp.
<jab>singpolyma: do you prefer using SML over scheme ?
<mwette>roughly speaking, in Scheme functional programming means not using procedures with `!' (like set!).
<lechner>jab / it was a bit of british self-deprecating humor. simon, who said that, invented haskell.
<jab>gotcha. :)
<identity>jab: note that e.g. the Haskell community tends to use more terms from Category Theory (abstract mathematics) compared to the community of Scheme, not to say we do not use them at all. Category Theory is kind of hard to get into (i mean, a monad is just a monoid in the category of endofunctors of some fixed category), but if you have some mathematics background, ‹Seven Sketches in Compositionality› is a good in
<identity>troduction
<jab>mwette: and not using loops. instead using recursion
<jab>thanks for the recommendation
<lechner>jab / you should try haskell. chances are you'll be back here in three years
<rlb>jab: for scheme you may also want persistent data structures like a persistent map, set, vector, etc. I thought maybe I'd seen some related srfis, but don't recall offhand.
<jab>lechner: I really like scheme. all of the developers that I admire love scheme. The syntax is so easy. It's easy to extend the language, though I need to dive into macros to really do that.
<jab>the scheme is weird but cool talk was super interesting to me.
<jab>sorry feel the cool
<jab> https://www.youtube.com/watch?v=tA1clbGDczI
<mwette> yep - super simple, elegent
<mwette>about simplicty of lisp: https://www.youtube.com/watch?v=OyfBQmvr2Hc
<jab>I suppose it would be possible to code in an APL type way inside scheme...
<jab>oh, racket has an APL language!
<jab>nope, not doesn't nevermind. maybe someone will implement it eventually.
<identity>there is an APL->Common Lisp compiler
<identity>implemented as an embedded language with a macro
<jab>wow!
<lechner>Hi, I see errors "while executing a meta-command." What are they, please?
<identity>lechner: like ,opt and ,language
<lechner>i am not in the repl https://bpa.st/YTJA
<lechner>i guess i used ,use
<lechner>okay, with use-modules it's "while compiling expression"
<identity>lechner: side-question: are the ‘and=>’s really necessary here?
<lechner>identity / probably not. I saw that somewhere else
<lechner>identity / thanks for pointing that out! i removed them
<lechner>Hi, does resolve-interface really have a #:prefix parameter like the manual says?
<lechner>okay, it just has to be quoted
<jab>hmmm. So one principle of functional programming, is to create a function, such that for input x there is always output y. I'd like to create a non-function program f(x) (that only via mutating variable values) that does not always output y. I know this sounds naive, but I have a hard time believing it is possible to define such a function...
<jab>I suppose one way to do that would be to have two fiber threads interacting with the same global variable...
<lloda>unless i misunderstand the question, all you need is to keep some state in the function, like (define f (let ((c 0)) (lambda (x) (set! c (+ 1 c)) (+ x c)))) ?
<identity>i think they mean that as in non-determinism
<identity>you can get a random number with (random n), which returns an integer x such that 0≤x<n
<jab>morning
<mwette>o/
<jab> I'm a little curious. Guile (and scheme in general) seems to encourage function programming. I had thought that closures were pure...but I just realized that the counter program is not pure. "+" is pure, because for any input you always get the same output.
<jab>the guile manual shows a closure example with a "shared persistent variable".
<jab>That's not pure either. Now I'm curious how one would write a toy financial database with pure functional programming. I feel like that's not possible, because you need to mutate state....
<ieure>jab, Most practical languages are multi-paradigm, Guile supports imperative, procedural, functional, and object-oriented. It is not purely functional. You're welcome to use a functional approach where it makes sense, and others where those make sense.
<jab>I guess, I'm just realizing that even in a language that is pure... eg: haskell...Even if you wanted to write a database in haskell, you still need to mutate state and have side effects. The point of functional programming, is that your core logic is pure, but the edges that affect the outside world, are not pure. This makes it somewhat easier to maintain your core bit of code.
<ieure>And this is the precise reason why most languages are multiparadigm instead of pure. Haskell threads that needle by using monads to model the IO in a functional way.
<ieure>But something like Scheme lets you pick your approach, as you say, you can model the core in a functional way and do the imperative stuff on the edges... mostly.
<jab>ieure: are you saying, that if one wants to be "pure" as must as possible, you can use monads to interact with the outside world ?
<ArneBab>jab: one point of functional programming is that you can make parts of your programs purely functional so they are easier to test and improve. It’s like ticking the box for them "these don’t have to be checked for side-effects"
<mwette>jab: to be pedantic, you could have a database program where every update generated a new database
<ieure>jab, I'm saying that Haskell has an IO monad which models the side-effecty nature of IO in a functional way. And you could reuse this approach, if you wanted to be purely functional.
<ieure>jab, I'm also saying, pure-anything languages tend to be inflexible, and it's easiest to model problems in their natural domain. And that is why most languages *aren't* purely functional... or purely OOP... or purely procedural.
<ieure>They're multiparadigm so you can use the one that best fits your problem.
<mwette>jab: check out "vlist-based hash lists" in the guile manual
<jab>mwette: I'll take a look. And a database program that updates the generated database everytime sounds super fast! :)
<jab>hmmm, immutable dictionary. interesting.
<ieure>jab, As others have mentioned, Clojure is a good case study here. The book Purely Functional Data Structures is also relevant, a lot of Clojure's inspiration came from it.
<jab>also is understanding monads the equivalent of understanding the general theory of relativity ? Seems like monads are super tricky.
<identity>jab: unless that was mentioned already, you can manage state by passing it explicitly as an argument to the function. instead of having a global variable *balance* and doing (add-to-balance 50) you would pass the balance in with (add-to-balance balance 50)
<ieure>identity, I mentioned this.
<identity>this is, essentially, the same thing that monads do
<identity>jab: monads are a really simple idea that just takes some getting used to
<jab>identity: that would imply that everytime someone does a financial transaction, you would need to create a new variable to hold the new value ?
<identity>really, most things in functional programming are really simple ideas that take some getting used to
<identity>jab: depends on what you mean by «create a new variable»
<jab>hmmm, I guess my question would be something like this then...
<jab>the guile manual gives an example of "A Shared Persistent Variable" using a closure. It lets one create the function get-balance and deposit and withdraw. How would one makes those functions functional? Is that possible or desirable ?
<identity>the 3rd chapter of SICP is a good explainer (really, the whole of Structure and Interpretation of Computer Programs is good)
<jab>I'll take a look at the 3rd chapter then.
<ieure>jab, Yes, it's possible, by writing the functions as (get-balance state) / (withdraw state amount) / (deposit state amount) -- each of one takes a state to operate on, and returns a new state. Then you pass the state from one function to the next.
<ieure>jab, Is it desirable, well, that depends on you and what you're building.
<jab>hmmm. interesting.
<ieure>When you have that model, you start thinking, dang, I sure do have to define a lot of these functions that take and return some state, wouldn't it be nice to abstract that to something like (apply-operation state operation)? And now you're halfway to monads.
<jab>ieure: I suppose that'll be a good exercise for me. To define get-balance, withdraw, and deposit without using any function that end in "!". Then when that starts to seem super annying, to add in monads.
<identity>jab: in a functional style, you would write ‘deposit’ as (define (deposit balance amount) (+ balance amount)), withdraw works as-is. then, instead of doing (let ((balance …)) …) (withdraw 50) (deposit 25), you could just do (let ((balance 0)) (withdraw (deposit balance 50) 25)) or even (withdraw (deposit 0 50) 25)
<identity>oh, i guess you are not going to do that exercise anymore
<jab>hahaha!
<jab>Just give me another one instead. :)
<identity>jab: anyway, i recommend reading all of SICP, it is a gold mine (with exercises!)
<jab>Just please don't ask me to write an operating system using only pure functions. :)
<jab>yeah. That's probably a really good idea!
<rlb>jab: this might also be interesting: https://hypirion.com/musings/understanding-persistent-vector-pt-1
<rlb>You can create a "functional" db by just always adding data, which can also also support "time travel". And given reality, I assume you'd also need a way to eventually drop older parts of the timeline. (I believe that's how datomic (not free) works.)
<jab>rlb thanks
<mwette>and occasionally you can create an updated db that removes unreferenced entries : garbage collection
<mwette>names