libera/commonlisp - IRC Chatlog
Search
1:29:45
shunter
Toplevel proclaims establishes declarations in the global environment. It's unspecified whether toplevel declaims have any effect after the file it lives in is compiled.
4:06:50
mfiano
Hello all. I have a couple ideas, but I'm looking for different opinions on how one might, if it was so required, to go about preventing the instantiation of a class, if that class is prohibitively intended to be used only as a super class, for some particular domain. Bonus points if you can argue why it is a good way to go about it.
4:09:13
mfiano
phoe: Yes, I meant, like kicking around the parens and stuff instead of moving to Java or something non-programming :)
4:22:56
dbotton
mfiano: just add a slot or use an existing slot with a uniform the signals an error is simplest way.
4:23:36
mfiano
dbotton: Then every subclass would be required to override that slot, which is an implementation detail. I don't like that at all.
4:27:08
dbotton
You can identify the type there and signal if they try and create your abstract class
4:27:54
mfiano
I think you are making an assumption that is not true. The un-instantiatable classes are mixin classes that can be provided to a variety of different objects, some whose constructors I don't control. Using stealth-mixin or dynamic-mixins, one can alter the super class list.
5:05:05
mfiano
beach: I think there is actually an error in that method causing it not to do what is intended.
5:27:27
mfiano
If I restart my image, define that macro, a protocol class using it, and a class that inherits from the protocol class, when attempting to instantiate the subclass, I get the error, but if I select the RETRY restart in the debugger, it works, and on all subsequent attempts without the debugger. I wonder if beach or jackdaniel could explain that one.
5:50:42
scymtym
i think i added the trick for preventing instantiation. i have to go now but can check the logs later
5:53:55
mfiano
I got it to work now. I was slightly modifying it for my purpose, and in doing so, I didn't realize that the initform was meaningless, and was just the quoted error form.
5:59:36
mfiano
As in it was unevaluated, and just there for display purposes or something when viewing the object in the inspector. An initform of nil, with an initfunction of the error is all it takes for it to work for me.
6:03:51
mfiano
code is doing `:initform '#1=(error ...) :initfunction (lambda () #1#)` which is quoting the first but not the second. I missed that subtle detail. The value of the initform does not matter much, as this slot is not inherited due to the EQL specializer on `compute-slots`, and it is not even evaluated yet before the initfunction error. At least that's what I gather by reading about it. Please
6:05:00
dirtcastle
Josh_2: thanks for the suggestion. I wonder which is the best language and book to learn OOPS. Lisp is not known for OOPS right...
6:06:16
beach
dirtcastle: The book by Sonja Keene is probably the only one exclusively dedicated to CLOS, but PCL has a lot about it too. Modern Common Lisp code uses CLOS a lot.
6:06:35
mfiano
and what makes it nice, is that it is fully extensible. The MOP is the CLOS as macros are to syntax.
6:10:02
edgar-rft
dirtcastle: the best book I read for learning CLOS is Sonya Keene's "Object-Oriented Programming in COMMON LISP: A Programmer's Guide to CLOS"
6:13:05
beach
ACTION now fears he is going to be given a list of predecessors with object systems in them,.
6:13:36
hayley
ACTION hopes the scare quotes suggests that she does not agree much with the "wisdom".
6:14:53
dirtcastle
yes. I heard common lisp has the ability to adapt to any new paradigm that comes around. And the comment I read said " common lisp has the best object system and that's ironic".
6:14:58
hayley
I told off a lecturer at my old university for making that statement. And the instructor for operating systems class had said similar for Elisp.
6:16:27
mfiano
beach: "lisp in general" also includes predecessor sibling branches developed independently of CL, some of which have CLOS-like or otherwise modern object systems.
6:16:43
hayley
Wouldn't state _any_ new paradigm, c.f. Felleisen's "On the expressive power of programming languages". There are some interesting things you cannot do with macros/local rewrites only.
6:16:55
beach
dirtcastle: It doesn't make much sense to "learn CLOS" in itself. CLOS is part of the Common Lisp language, and you use it together with the other features.
6:16:59
dirtcastle
lisp is known for using procedural & functional style, recursion and macros. and lambda functions?
6:17:25
hayley
I'd go easy on recursion, as only the Scheme standard mandates tail-call elimination.
6:18:59
beach
ACTION can't figure out why there is this desire to teach him about Lisp, compiler design, programming-language implementation, etc., when he is attempting to use his pedagogical skills to inform newbies.
6:19:45
dirtcastle
I just read abt languages in reddit and hackernews and stuff. for the past couple weeks I've been visiting 4chan's /g/ board extensively.
6:20:43
mfiano
No, I'm just stating facts, not directed at you, except the last one. If this bothers you, I apologize. Maybe public forums are not your preferred venue?
6:21:23
beach
mfiano: The one that started with "beach: "lisp in general" also includes..." was not directed to me?
6:22:27
beach
mfiano: Yes, you may be right. I conclude that I should try to shut up. But that would be sad because some newbies think my remarks are helpful.
6:22:33
mfiano
That was "the last one". What do you not like about that fact? I was not speaking of CL predessors, but Lisp predessors that have evolved independently of CL that cannot be ignored with "lisp in general"
6:23:03
beach
mfiano: Like i said, I don't like to be lectured on things I know, when I am making pedagogical simplifications to newbies.
6:24:16
mfiano
Tutoring is best done in a more controlled environment. If you don't like comments in a forum of hundreds, then I'm sorry for you.
6:27:07
hayley
I think people not familiar with Lisp consider members of the Lisp family as more homogenous than the members are. So it is plausible for people to derive misconceptions about Common Lisp from other languages. But maybe I should shut up too.
6:28:54
mariari
From Oleg "My overall impression from ILC02 was that Lisp and Scheme, despite the common syntax, are different languages and communities. I think Python is closer to Haskell than Lisp is to Scheme. Common Lisp (CL) seems to me like a Smalltalk with round parentheses. Scheme community is more diverse, valuing the functional approach. In contrast, CL community seems more pragmatic and more ad
6:37:55
frodef
To me the essence of CL is the principled approach to dynamic scope. Which is (or should be) extremely important for good programs.
6:48:36
_cymew_
Not to make fun of ayone, but for me the essence of CL is people obsessed with scope in all shapes and forms.
6:54:36
frodef
also one of the best use for macros is to enable readable dynamic context constructs. WITH-foo that makes precise boundaries with precise semantics.
6:58:48
_cymew_
I'm a spectator in quite a few programming language communities online, and some talk about what they are doing and their projects. Others mainly talk aout how to implement compilers, and some talk about scope more than anything.
7:00:52
_cymew_
To emphasize my experience. I once had a guy notice the lisp sticker on my laptop, and he approached me and started asking my opinion on lazy evalation and scope...
7:02:11
mfiano
Regarding preventing instantiation: the previously discussed MOP method is very nice, however, is there any solution, or can this be adapted, such that these "protocol classes" can be instantiated internally? For example, there may be a constructor function whose symbol is exported, and also the class-name symbol is also exported, but the intent is for the user to never use `make-instance`
7:02:13
mfiano
directly on the exported class name, as that could cause disastrous consequences. But, internally, the supplier may need to instantiate it for it's own purposes.
7:02:27
frodef
I'm writing some software to juggle around data from "web applications". It's information that should be in the kilobytes, but through the magic of XML and combinatorial explosion, it's easily becomes hundreds of megabytes. It's incredible to behold.
7:03:41
frodef
..and the web-apps themselves somehow put a hefty load on a modern desktop machine, occasionally just bogging down under intense memory and CPU overutilization.
9:02:20
mzan
dirtcastle: I'm not an expert of CL, but I'm starting using it. As functional programming language is not on par with OCaml and Haskell. By default it has no algebraic data types and persistent data structures. On the good side, there is that functions can be passed as arguments. Rarely functions are returned as results. Macro are used instead.
9:03:02
mzan
You can use CL libraries with persistent data structures and algebraic data structures, and there is also Coalton.
9:04:04
mzan
So if you want, you can use it as a FP. But, the majority of CL code does not follow this approach.
9:07:31
mariari
on the side of functional CL, you can do some FP idioms that are common in Haskell and OCaml better than in OCaml and Haskell, as you can have arbitrary sum types which helps with idioms quite a bit and regain exhaustion through serapeu
9:08:45
mariari
I tend to write my CL mostly functionally, where you can even derive your own updater functions easily enough, once one uses CL for a decent amount of time, you can basically treat it like any other functional language but with a proper environment to help one code
9:10:29
Josh_2
I dont think its controversial to say that the defacto way of writing cl is using Generics
9:13:46
mzan
mariari: I'm checking https://github.com/ruricolist/serapeum interesting. Thanks. Are you able to declare some algebraic data types in advance, like in Haskell?
9:15:22
mariari
this works much better than any ML I've used as the or's can be nested. I really should send in a patch to them to improve the exhaustion warning, as it doesn't always give a nice message
9:15:55
mariari
the direct-pointwise-mixin here just lets me derive generic object equality, much like you'd derive Eq in haskell
9:16:00
mzan
mariari: nice. In Haskell, datatypes definitions are often one of the entry point used for understanding some code. In CL without extensions, I lack this type of documentation.
9:18:08
mariari
the only issue I tend to have, is that I use high test coverage to make sure they are consistent, but at least SBCL does check if you try to pass in the wrong type (CCL tends to care less on the default settings)
9:19:10
mzan
pve: poor man, because they are references but they can be managed also like values. But if you are not disciplined, you can insert bugs in the code. Instead in Haskell anything is a value, i.e. persistent. So you cannot insert errors. But it is fair: Haskell was designed decades after CL, and it is dedicated to only one paradigm.
9:19:34
mariari
serapeum gives you defadt, but i don't use it as it defines out structs which I don't like using these days
9:20:44
mariari
the defadt in the library also removes the writer fields for the structs, so they are basically pure values
9:21:44
mzan
mariari: thanks. I copy and pasted your notes on the notes of my current CL project, and I will study them better. Interesting.
9:22:36
mariari
no problem, it was a breath of fresh air writing a compiler in CL after having writing one for a long time in Haskell, CL is just more flexible in how you can represent data. Like with c2mop you can derive generic traversals with protected slots etc
9:23:21
mariari
I've done this in haskell in the past, and it was a pain, as you basically just define your own Sexp type, as AST's in the ML style just don't scale due to how rigid they are, since they can not be adhoc
9:24:37
pve
mzan: I understand what you mean, but "decades after CL" is probably not an accurate statement
9:24:39
mzan
Josh_2: I made some toy projects in CL. Now I'm writing a live environment for a Knowledge-Base language, and maybe in future, assuming I will finish the first part, also for a compiler for a language based on attribute grammars
9:26:24
mzan
mariari: yes, static typing is useful, but it limits freedom. Sometime, you need freedom for expressing powerful things. I hope that with the serapeum approach, one can have both freedom and some safety. I will study it better.
9:27:54
mariari
if you look at my alucard codebase: https://github.com/anoma/juvix-circuits/tree/main/src you'll see most code written in this style, mostly purely functional with some mutation to get things done at the top and to setup the mixing of languages
9:28:12
mzan
Josh_2: the code is not packaged using ASDF, but this toy project https://gitlab.com/massimo-zaniboni/snow-assembler
9:28:29
mariari
but checkout the intermediate folder for the data layout and the pass folder for the various compiler passes, you simply can not do this style of development in ML, I'd argue this style is much safer than the ML approach as well
9:28:52
mzan
Josh_2: and these toys programs for benchmarking CL https://aoc-benchmarks.dokmelody.org/linux/overview.php
9:29:19
mzan
this code https://aoc-benchmarks.dokmelody.org/linux/program.php?test=aoc2021_day03b&lang=lisp&id=3
9:39:18
mzan
mariari: BTW, it is written in Scheme, but it can be ported to CL for sure. One of the best framework for specifying compilers is Nanopass. This an example of code: https://github.com/nanopass/nanopass-framework-scheme/blob/main/tests/compiler.ss
9:39:40
mzan
If you read the define-language parts, you see algebraic data types, and they are better than in Haskell, regarding the domain of PL.
9:40:43
mariari
the problem with the ML style of design is the typing makes them lose sight of the problem at hand, often you'll find giant passes as the rigidness of ML ADT's are simply too inflexible for real compiler work, and the approaches out of it (Tagless final, trees that grow, etc etc) are too hacky
9:41:33
mariari
yeah I've read their paper before it looks neat, never played with it personally, but I'm with them on smaller style of passes as they become more trivial to reason about, and prove if you really wanted to
9:45:35
mariari
the thing about lisps is that you have the freedom to define your own static analysis tools, as you have readily more access to the format of data if you so desire, writing tools in Generic in Haskell is a pain and encures some runtime costs, and since you can't augment the system you are stuck with what you are given
9:46:11
mzan
One minor detail of Nanopass, but that is wonderful, is that like in math/CS, you can specify new intermediate languages (IR) specifying only the differences respect the previous IR. It is a very compact notation. A lot better than Haskell notation, for this domain. Lisp is fun!
9:48:04
mariari
mzan: I don't use this in the code I sent since serapeum's default checker does not work with it, but you can do something similar with deftype (deftype modified-thing () `(or if (not cond) ast-with-cond))
9:48:31
mariari
mzan: I don't use this in the code I sent since serapeum's default checker does not work with it, but you can do something similar with deftype (deftype modified-thing () `(or if (and (not cond) ast-with-cond))) might need an and there
11:54:42
lisp123
mariari, I hate this ongoing perpetuation that CL is not functional - it is multi paradigm and generic functions are a way to merge an OO approach with the functional underpinnings of lisp
11:55:37
lisp123
The syntax of CL encourages a largely functional style as side-effects are isolated within functions
12:05:28
mariari
the funny thing about generic functions is that they would feel at home for those who come Haskell and its derivatives (they would call them type classes). But yeah I largely agree with your sentiment. The compilers nicely support the functional style speed wise as well