freenode/#lisp - IRC Chatlog
Search
14:54:10
zmyrgel
its odd as make-pathname call seems to create proper pathname for the sub directory
14:54:41
zmyrgel
but then the directory-files seems to list files at 'alerts' directory for some reason
14:56:12
zmyrgel
I'd like to have the list-customer-alerts function return list of *.net files in customers directory
14:59:26
_death
zmyrgel: if it's a subdirectory, you should (merge-pathnames (make-pathname :directory (list :relative customer)) *alert-dir*)
15:09:19
schweers
I have not tried this, but I think using :name customer is a mistake. This means that you have a file with the name of the value of CUSTOMER, instead of appending said value to the directory part of the path.
18:11:36
Oladon_work
xivh: How are you determining that it "doesn't actually rewrite the function"? Are you sure you're not dealing with closures?
18:13:34
xivh
I have a defun in a file, I can do C-c C-c to recompile as I edit it. Then I load a file with unit tests, and after it runs, C-c C-c says it is compiling but the function will not change unless I restart slime.
18:15:09
xivh
I know it isn't rewriting the function because if I start slime and run the unit tests, then do C-c C-c and try to use the function, it says it hasn't been defined.
18:18:20
Oladon_work
That doesn't sound like a slime issue. Have you tried the same thing in your basic REPL?
20:35:08
vms14
I want to read some lisp code, I still being a lisp noob, do you have some suggestion to look at?
20:38:39
moldybits
quicklisp? i don't know. any project that interests you. it's not like you have to read all of it to learn something.
20:40:00
vms14
but wanted to know if someone had a recommendation of some code that thinks it's well written or easy to understand for a beginner in order to learn
20:47:06
vms14
Josh_2: I'm more interested atm to convert oop code to fp, but no idea about how, I know closures are the way, but that's all
20:48:28
White_Flame
but I really recommend against the LoL style in practice, because it's opaque and not interactively editable
20:48:48
White_Flame
also, it's not functional programming. It stores the object in a closure, but is still all about mutation
20:49:14
Josh_2
Why not just leave OOP as it is and then write some other stuff as functional programming
20:49:19
aeth
vms14: As far as FP goes, I think CL is best when the FP is limited to simple values, and the complicated data structures are mutable. So at the top level you SETF slots (standard-objects, structs, hash-tables, arrays, conses, whatever... you can avoid doing this for variables, though), but most of the functions from that level can be pure
20:49:49
aeth
vms14: I mean, a trivial example that seems pointless is (setf (aref foo 42) (+ x y)) ; pure function feeds into a mutable data structure
20:50:32
White_Flame
it's good to limit a lot of your internal processing to being functional, and at the outer periphery manage your mutations. Deep internal mutations is usually where problems leading to a fp solution occur
20:50:55
vms14
would fp be a good way to represent a product, item, whatever has some data to represent, over oop?
20:51:27
White_Flame
I much prefer data-oriented programming, instead of bolting functionality in with data
20:51:46
aeth
vms14: If you can express it as multiple return values, then pure FP is fine in CL, but with the disadvantage of not really having any real explicit structure there. Imo.
20:51:52
White_Flame
and what do yo mean by "a product"? The result of multiplication? A function that multiplies?
20:52:05
vms14
but how fp would be more useful than oop representing data that oop can handle easily?
20:52:30
White_Flame
take the methods out of an object. Then it's a struct. There you have a FP data structure :-P
20:52:42
vms14
it's just a way to abstract data, but I want to know what could offer functional programming
20:53:51
White_Flame
functional programming is simply passing around data, and when things change, return new data
20:54:14
White_Flame
for isntance, vector addition would return a new vector instead of mutating one of the input vectors
20:54:17
aeth
CL is more a language for writing functional languages than a functional language in itself. You have to add a lot of optimizations and tricks if you want to get efficient pure FP that you'd get for free from some language where that is its focus. Unless, of course, you can settle for multiple return values, in which case there isn't really a cost to returning (values 1 2 3) instead of (values 4 5 6).
20:55:13
aeth
The exception imo is probably macros. Those are complicated enough without microoptimizing them when they're running at compile time anyway. Just treat lists as if they're pure in macros even though they're not and even though that means your code is going to cons more and run slower.
20:55:44
White_Flame
the problem with OOP is that you often end up with a deep, tangled web of object references behind your 1 "easy' object, such that when you call anything there are arbitrary unexpected mutations triggered down the chain, and taht affects other objects
20:55:53
aeth
(And it's not like you could use a purecons data structure in macros anyway, since you have to return conses)
20:56:32
White_Flame
plus, it can be much harder to test things in OOP because you have to have a ton of live objects instantiated, vs just a data representation
20:56:57
aeth
White_Flame: Those problems can usually be (mostly) solved by not having elaborate inheritance hierarchies, which certain GUI toolkits/frameworks love to do.
20:56:57
White_Flame
it's also good to remember that not everybody has a microoptimization fetish ;)
20:57:40
aeth
White_Flame: my point though was that in a pure FP language, ideally the microoptimizations to reduce consing are done for you, which isn't the case in libraryless CL
20:57:47
White_Flame
aeth: well, if you have cascading mutation event handlers, loggers, debugging hooks, indexes of objects, etc, the chain still gets deep even without frameworks and such
20:58:26
White_Flame
even just mudballing "normal" code, or going through basic iterative design changes can really tangle up OOP projects in a hidden, behind-the-scenes way
20:59:26
aeth
White_Flame: For most people, threading is where you want to run 8x faster on your 8 cores, but you wind up running 0.8x faster and with things no longer happening in the correct order. :-p
21:00:38
aeth
White_Flame: One of the main pitches of FP is that if everything is functional, then e.g. switching from MAP to PMAP is trivial.
21:01:17
White_Flame
(and yeah, "functional programming" used to mean programming with first-class function objects, hence the "pure" label now)
21:03:14
White_Flame
where "pure functional programming language" is a language that prevents you from mutating at all, while "functional programming style" can be done via design & programmer discipline in any language
21:03:26
aeth
If CL (or an implementation) let you label a function "pure" (some languages let you do that) then (afaik) you wouldn't be allowed to SETF/SETQ in it or call functions that indirectly SETF/SETQ
21:03:56
aeth
and perhaps if it's more sophisticated you'd be able to SETF/SETQ, but only if it doesn't leave the scope, like a temporary i variable in a LOOP
21:06:13
aeth
White_Flame: A pure-declared function would work fine, you'd just have to treat it like a potentially inline function unless it was also declared notinline
21:08:55
aeth
White_Flame: imo the two most useful things to declare on a function that you can't yet do (afaik) would be "pure" and "tail recursive", where the latter could force TCO even at high debug and low speed, where those implementations with TCO would probably normally disable it.
21:09:37
aeth
vms14: If you're willing to accept info (which can run in emacs) as the superior alternative to man pages, I think someone made an info version of CLHS
21:10:57
aeth
Bike: Why not both? A tail recursive declaration makes sense if it's self tail recursive or mutually tail recursive with another function like a calling b calling a calling b. Marking individual calls as tail might make sense in other contexts.
21:34:25
Oladon_work
I think I'm late to the discussion, but something which bothers me a ton is the recent trend of writing reducers "in a functional style" and copying the entire object each iteration just to add or change something.
21:35:22
White_Flame
Oladon_work: in an ideal world, with a Sufficiently Advanced Compiler™, that still could be optimized away
21:35:45
White_Flame
but yeah, when it's explicit, and its transient use like that, it might just be a needless big performance hit
21:36:00
Oladon_work
Oh, I wasn't talking about optimization, actually — my comment was while I was reading up and people were talking about mutability as if that's what functional programming is All About
21:36:24
Oladon_work
For me it's more the complexity that it adds... for no gain except being able to say "it's Functional!"
21:37:40
Oladon_work
I see it most often in JS: foo.reduce((item, result) => { return [...result, [foo.name]: transform(foo)] })
21:38:37
Oladon_work
Congratulations, you've avoided mutating "result", which exists only within your reduce operation (which should really be a map operation anyway, but...)
21:40:25
White_Flame
if an object exposes operations that are pure FP, then that's fine, just use them even when a mutation would be faster, because the operation is there & available. But to just bolt in weirdness like that is just weird
21:41:12
Oladon_work
Yup. Yet it's extremely popular right now, because "Functional Programming is the future, and Functional Programming = immutability!"
21:42:06
Oladon_work
Btw, I'm still hiring if anyone wants to come write Lispy JS on an actually-very-cool team doing cool stuff. :)
22:18:44
Oladon_work
Ah, that seems like a plausible interpretation. We're looking for senior developers, and the position is onsite.
22:22:22
aeth
White_Flame: In something like CL, you'd need to be able to mark data structures as pure, and for conses, since they're so simple, you'd need a separate immutable cons (icons or something). Even sufficiently smart just wouldn't work with CL's recompilation semantics and debugging ability.
22:25:35
aeth
Oladon_work: In some languages, like Python 3, stuff like map() don't cons up a new "list" (really, vector) anymore unless you explicitly convert the result into one. I guess it's sort of like a lazy sequence. That can avoid some of the overhead of certain FP styles. In CL, you'd probably just want to refactor a MAP into a MAP-INTO, though, if possible, so there's probably less of a demand.
22:26:53
aeth
It's funny seeing a language (JS) where you afaik run it in one thread emphasizing immutability so much, though, since the main initial pitch of languages like Clojure or Haskell 10 years ago is that immutable data structures are easier to work with in threads.