libera/#commonlisp - IRC Chatlog
Search
13:53:44
jjnkn
hi, i'm learning about methods and there is something i'd like to get advice on; i'm trying to generate methods with macros; in particular, my macro should be able to generate multiple methods that have the same parameter specializers; as far as i understand, the method system doesn't allow this; so how can i benefit from type specialisation in this case? is it possible to perform some compile-time
13:56:41
jjnkn
i should provide more details, return values of my methods don't matter, their purpose is to perform validation, so they either raise a condition or don't; therefore, it would be enough to simply run them sequentially
13:58:33
beach
You could have two methods with the same specializers if they have different qualifiers, but then you would need to define your own method combination.
14:01:38
beach
If defining a method with the same specializers as an existing method would result in the new method being added, then each time you load your system again, you would get more and more methods.
14:02:13
beach
And if you made a mistake in a method code and attempted to define it again, the incorrect method would not be removed.
14:02:47
jjnkn
okay, how about this: in my macro i check if a method with given parameter specializers already exists, and if it does (call it 1st method) i "wrap" it into the 2nd method (the one being defined by the macro)
14:03:28
jjnkn
that's where i think some compile-time magic should happen, as i know little about compile-time evaluation in Common Lisp
14:03:33
beach
You can't call methods. You call generic functions, and the generic function selects which methods to call an in which order.
14:04:45
_death
you could define a single method with a body that's built out of multiple forms.. or keep multiple functions around to call
14:05:34
beach
You can stick your functions in a hash table and call each function in the hash table.
14:07:51
jjnkn
i have already tried the hash table approach, but couldn't replicate type specialisation, since a key will correspond to a single type (i.e., functions keyed on 'string will not be found for (simple-array character)
14:09:24
beach
Maybe if you tell us what you are trying to accomplish, we could suggest a solution that works.
14:13:09
_death
you could, again, define a single method with multiple forms for a particular class if needed, but have the GF use progn method combination so that methods defined for superclasses would also be called by the GF
14:16:19
jjnkn
i'm trying to create a system to define classes with validation of their slots; validation takes place when a slot's value is being set; i want my validators to specialise on the type of value being set
14:17:22
_death
CLOS does not support dispatching on types in general, so if you wish to do that you'd have to write your own dispatching code
14:17:40
jjnkn
i want to be able to set a DATE from a string (e.g, 2022-01-01) and from an integer (e.g., unix time)
14:19:45
jjnkn
_death: what do you mean? am i misunderstanding the concept of method parameter specialization?
14:23:44
_death
you could have something like (loop for validator in (slot-validators object 'date) when (validates-type-p validator object 'date new-value) do (validate object 'date validator new-value)) and have some fallback when there's no appropriate validator
14:24:26
_death
(validates-type-p should also take a validator; this snippet was for illustration purposes only)
14:27:01
jjnkn
_death: i am considering roughly the same approach as you proposed, but wanted to find out whether i could employ generic functions for my purposes
14:30:22
beach
jjnkn: If you insist on wanting several methods with the same specializers, I think the answer is no.
14:35:58
_death
is it important to define validators for a given slot separately and incrementally? if not, why not a simple (deftype order-date () '(or (and string (satisfies date-string-p)) (integer 0))) and have :type order-date for the slot? in fact to me it seems poor to have a slot contain multiple representations of a date after validation.. I would just pick a single representation and validate possible inputs elsewhere as part of translating
14:39:03
jjnkn
_death: i'm not familiar with the DEFTYPE form but regarding the 2nd part of your message: a slot can contain a single, fundamental, representation, but can be set from different ones by means of translating inputs
14:40:09
jjnkn
i'm still not certain whether it's a must to be able to define validators incrementally
14:40:45
jjnkn
seeing that it's not a trivial task, i'm probably going to stick with a simpler non-incremental approach for now
14:40:48
_death
so (defmethod (setf date) ((new-value string) order) (setf (date order) (convert-to-unix-time new-value))) ?
14:43:33
_death
it's kind of weird to set date to something and then get it back and it's a different object, so I'm not sure I would use such methods for that (although it should return new-value)
14:44:58
_death
*use setf methods for that.. I'd maybe have a set-date GF that takes a "date designator"
14:50:09
jjnkn
in fact, a representation is allowed only if it has a mapping function from the fundamental type (for setting the slot) and a corresponding inverse function (for reading the slot)
14:51:50
_death
so that's another reason not to use the accessor.. you'd want to provide the desired representation type as an argument, like (get-date order 'iso8601-with-fries)
14:53:28
jjnkn
there are also performance considerations: for example, if the inverse mapping function is computationally expensive
14:54:16
_death
anyway, if you want validate or translate from multiple representations having the same class, you need to handle that yourself in a single method
16:06:27
didi
Is this expected? I have the following file https://paste.debian.net/hidden/00bb7521 . I then eval in another package (defvar *bar* foo:*foo*) and (eq *bar* foo:*foo*) => t. All is good. But, if I compile the file in SLIME using C-c C-k, (eq *bar* foo:*foo*) => nil. I'm using SBCL.
16:11:08
gilberth
It is. When you compile and load that file foo:*foo* is set again with DEFPARAMETER to a new (3 . 4) different from the previous one that *BAR* still has.
16:13:02
didi
So I need to think of another way of setting a sentinel that I can test using EQ and that will survive recompilations.
16:14:12
gilberth
DEFVAR only sets the variable when it has no value yet, while DEFPARAMETER always sets the variable.
17:29:35
Josh_2
adding it as dependency broke my build pipeline because it depends on sqlite... :sob:
17:57:06
semarie
Posterdati: could you define "broken" a bit more ? which lisp implementation ? which error ? etc...
18:16:03
ecraven
is there a generic database library, that can do sql queries to different database backends?
18:25:39
jjnkn
when i tried cl-dbi i encountered an issue with executing multiple sql statements at once; i wanted to run an sql script, so i just read the whole file and tried to execute its contents but cl-dbi signaled an error