libera/#commonlisp - IRC Chatlog
Search
20:59:39
White_Flame
as such, the standard does not specify _anything_ about what's in the environment object, and you cannot change it without being non-portable
21:00:28
White_Flame
a singular evaluator object would be more comparable to an interpreter, because it would have to take s-expressions
21:00:49
White_Flame
a compiler would have to do weird and expensive dispatching to cache compiled forms if it obeyed such an evaluator API
21:01:02
nij-
Hmm.. are you saying what I been using is not a repl, but a rcpl (read-compile-print-lop)?
21:01:25
White_Flame
which of course is expensive cmpared to compile once and execute as many times as you want
21:02:02
White_Flame
so if you have an "evaluator" object, which by the vocabulary lisp would take s-expressions, then jacking in a compiler would have impedance mismatch with the API's assumptions
21:02:15
White_Flame
and this is a "lock-in" of overspecifying the implementation, as I was talking about above
21:02:58
Bike
there's a balance between exposing things to the user and overly constraining the implementation
21:03:08
Bike
there used to be an *evalhook*, which you could bind to some function that would do evaluation
21:03:12
White_Flame
and how much nonsense would it add to your workload if you were writing a simple interpreted CL?
21:03:25
Bike
but that pretty much required lisp to do an interpreter in a way that's very constraining and slow
21:03:57
White_Flame
nij-: interface = the set of functions, datastructure, & call ordering you need to make it owkr
21:04:53
Bike
there are some existing hooks into the compilers, like macros. that has an interface via defmacro, macroexpand, bla bla
21:05:18
White_Flame
the CL standard was written to allow implementations to make smart compilers, dumb compilers, interpreters, and support a whole host of variety of hardware as existed back then
21:06:09
White_Flame
making an assumption that a compiler has to work like X and must have Y knobs to help implement your feature constrains the design of the implementation
21:06:51
White_Flame
"the compiler has this hook/knob/etc" is assumptions about the design of the compiler
21:07:02
nij-
But I'm thinking of a possibility for the user to hack it without going into the source.
21:07:17
White_Flame
what's nice about (declare (optimize (speed..) (safety..) ..)) etc is that it doesn't mandate any specifics
21:07:29
Bike
nij-: but the compiler would have to support some mechanism to let the user do that, is the point
21:07:43
White_Flame
ahd thus compilers can be wildly different, they could JIT, they could do whatever, and the same options still apply
21:08:04
White_Flame
nij-: hacking _is_ getting into the source. what you're talking about is configuration
21:08:35
White_Flame
basically turning the spec into a dynamically editable language specification. Which is fine for research languages, and many do, but a spec must draw lines somewhere
21:09:55
White_Flame
oh asking me? yeah, when creating a new language, many things are dynamically configured, until you decide what features you want to standardize on
21:10:27
White_Flame
and then you can get a lot of holistic interactions between solidly designed components instead of everything having to interact with moving targets
21:11:22
White_Flame
and that's not something languages include in their core, because then what do you design to?
21:12:21
Bike
more flexible lisps in this respect include maru, where eval is a generic function, and kernel, where you can define your own special operators
21:12:36
White_Flame
but still, if you have a CL running in front of you, you can code in it, or hack the CL implementation itself to bend to your will & features ;)
21:12:43
Bike
so you could look into those if you're interested, but they are, as white flame said, pretty much research languages rather than something usable for your program
21:13:25
White_Flame
the slightest change that you make to the CL evaluator would semantically make a whole new language
21:13:29
nij-
I wish to be able to switch to another CL-package, and voila, the evaluator has now changed.
21:14:43
Bike
because you clearly have something you want to specify, it's not like it would be done for you
21:14:59
White_Flame
and again, you can shadow DEFUN/LAMBDA/etc in your own package and run through your own transforms, and keep it 100% portable CL
21:16:36
Bike
say there was a generic function FUNCTION-LOOKUP, that took a function name and an environment, and looked up the name to return the function
21:17:10
White_Flame
we'll conveniently ignore the case of looking up FUNCTION-LOOKUP itself, right? ;)
21:17:33
Bike
then you defined a method (defmethod function-lookup ((name keyword) env) (lambda (plist) (getf plist name)))
21:17:49
Bike
so then (:foo a) evaluates to ((lambda (plist) (getf plist :foo)) a), which is i think what you had in mind
21:18:29
Bike
the user could define whatever method on function-lookup at any time, so the compiler can't actually look up anything up ahead of time
21:19:14
Bike
this isn't the only possible interface, obviously, just the first one that popped into my head
21:21:05
White_Flame
declarations, macroexpansions, etc, are all used by the compiler at the current state that they're set when the compiler is invoked
21:21:24
White_Flame
if you change those things in the environment, the compiled code does not change to reflect them
21:21:36
Bike
the metaobject protocol is a good example of the effort that goes into making some part of the language more flexible
21:22:26
Bike
it lets you warp CLOS into a whole lot of different things, if you want. i've implemented something like python decorators using it, cl-json has self/javascript-style prototype programming
21:22:28
White_Flame
and what is set at compile-time, and what is undefined consequence to change after it's been used, etc, is tackled a lot by the CL specification
21:22:50
Bike
but they had to put a lot of thought into how the MOP interface would be designed, so that it isn't so free that the implementation has to do everything slowly
21:23:18
Bike
and also so that users could use objects without having to fear that some extension would pull the carpet out from under them
21:25:13
nij-
What I want is a way for the target lang to send a message to the host lang that changes stuff there.
21:26:26
White_Flame
it's good for flexibility, it's bad for ecosystem & portability, it's bad for practical implications of speed & scale
21:27:18
White_Flame
and again I think the optimization declarations in CL are a great example of sending a level of information to the compiler that is applicable for any architecture the implementation happens to use
22:12:50
jcowan
I think this is a complete list of the types that have representations in standard syntax (disregarding sharpsign-dot expressions): numbers, symbols, conses, strings, characters, simple vectors, and bit vectors. Am I missing anything?
22:35:31
aeth
keywords are kind of sort of different from symbols in that they're :foo instead of keyword:foo so you could include them on the list
22:36:10
aeth
since you could view them as being of a subtype with its own representation in standard syntax
22:37:11
aeth
along those lines, you may want to consider complex numbers with the #C(...) syntax separate from the other numbers
22:39:36
aeth
(which is a difference from Scheme, where they have a very number-y representation, not unlike the rationals)
23:05:12
White_Flame
you'd also split up float vs int with that syntax-level distinction, but I don't think that's as meaningful to the list
23:33:29
seok
Anyone know whether zpb-ttf can return all character code points available in the ttf or I have to implement a loop looping through all code points with glyph-exists-p?
23:57:15
jcowan
Okay, thanks, so pathnames are included. Random-states are readable/printable, but have no specific syntax.
8:35:19
pjb
nij-: When the answer is "No", it means it's not trivial to do. You can always do it, with sufficient work. If you want to change the evaluation rules, you may do something like in cl-stepper. https://gitlab.com/com-informatimago/com-informatimago/-/tree/master/common-lisp/lisp
8:36:08
pjb
nij-: then instead of (defpackage "MY-PROGRAM" (:use "CL")) you'd write: (defpackage "MY-PROGRAM" (:use "MY-RULES-LISP"))
8:41:55
pjb
nij-: as mentionned, there's no standard way to change the evaluator (ie. EVAL, COMPILE and COMPILE-FILE). BUT you can either feed the evaluator some changed code like cl-stepper does, thru different macro expansions, OR you can use a different evaluator: write your own MY-RULE:EVAL, MY-RULE:COMPILE, MY-RULE:COMPILE-FILE, and the functions that call them such as MY-RULE:LOAD, and use them instead of CL:EVAL, … CL:LOAD.
8:42:53
pjb
nij-: note: this is a common occurence, for example, CLIM defines its own objects and methods. A clim application (:use "CLIM") instead of "CL", and you get clim:defmethod instead of cl:defmethod, etc.