Hi,
in general, I don't like the way ASDF tries to force you to comply with its own design choices and policy. This is especially true for component versioning. ASDF complains that it doesn't like my version numbers (which, in fact, are not only numbers ;-), but I'm not ready to give up on them. They're much more informative than ASDF's simplistic 1.2.3.
It seems that the only place ASDF uses our version numbers is in VERSION-SATISFIES. There is also a VERSION-COMPATIBLE-P somewhere, but it doesn't seem to be used. Fortunately, VERSION-SATISFIES is a generic function, so I'm thinking I could work around it.
Not tested yet: 1. (defclass my-system-subclass (system) ()) 2. (defsystem :foo.bar.baz :class 'my-system-subclass #|...|#) 3. (defmethod version-satisfies ((c my-system-subclass) version) #|my own version handling code|#)
Thoughts ? Will this be enough to satisfy ASDF ?
In an ideal world, the whole versioning API (version-satisfies, version< etc.) should have been implemented as proper component-based protocols...
I wrote:
Thoughts ? Will this be enough to satisfy ASDF ?
Not quite. I missed NORMALIZE-VERSION (ASDF attempting to be clever and doing all sorts of nasty DWIM stuff on version numbers).
Attached patch would solve the problem, it seems. But then again, I don't really know what I'm doing. It wraps NORMALIZE-VERSION within a generic function which I can then specialize on my system, essentially bypassing normalization altogether, like this:
(defmethod asdf/parse-defsystem:normalize-component-version ((system my-system) form &key pathname component parent) (declare (ignore pathname component parent)) form)
Didier Verna wrote:
Hi,
in general, I don't like the way ASDF tries to force you to comply with its own design choices and policy. This is especially true for component versioning. ASDF complains that it doesn't like my version numbers (which, in fact, are not only numbers ;-), but I'm not ready to give up on them. They're much more informative than ASDF's simplistic 1.2.3.
Counterpoint: humans have to be able to read and compare the version numbers reliably too. I have a tendency to prefer intra-system-definition-facility standardization of version formats for that and similar reasons (for instance, Debian packages have a similar albeit richer constraint). I would be more in favor of a way of specifying both "standardized version" and "flavorful version".
Weaker counterpoint: metadata analyzers may want to read version numbers without having to integrate arbitrary code from the systems too (but I don't know whether this is currently practical in the first place).
Curiosity: what _are_ your version numbers like, and how do you compare them? It was a little too hard to find this readily from your website. Maybe seeing a good example would help.
---> Drake Wilson
Drake Wilson drake@dasyatidae.net wrote:
Curiosity: what _are_ your version numbers like, and how do you compare them? It was a little too hard to find this readily from your website. Maybe seeing a good example would help.
A version specifier has a major and a minor number, a status (alpha, beta, release candidate and patchlevel), a status number and a name.
This is the beginning of the VERSION function in all my libraries:
(defun version (&optional (type :number)) "Return the current version of Clon. TYPE can be one of :number, :short or :long.
A version number is computed as major*10000 + minor*100 + patchlevel, leaving two digits for each level. Alpha, beta and rc status are ignored in version numbers.
A short version is something like 1.3{a,b,rc}4, or 1.3.4 for patchlevel. Alpha, beta or rc levels start at 1. Patchlevels start at 0 but are ignored in the output, so that 1.3.0 appears as just 1.3.
A long version is something like 1.3 {alpha,beta,release candidate,patchlevel} 4 "Michael Brecker". As for the short version, a patchlevel of 0 is ignored in the output."
Didier Verna didier@lrde.epita.fr writes:
Hi,
in general, I don't like the way ASDF tries to force you to comply with its own design choices and policy. This is especially true for component versioning. ASDF complains that it doesn't like my version numbers (which, in fact, are not only numbers ;-), but I'm not ready to give up on them. They're much more informative than ASDF's simplistic 1.2.3.
Alternatively, we could have:
(defsystem :foo :version-major 1 :version-minor 0 :version-release 42 :human-readable-version-string "1.0.gamma.XLII/pescadero:whasaaaaa")
or:
(defsystem :foo :version (1 0 42) :human-readable-version-string "1.0.gamma.XLII/pescadero:whasaaaaa")
"Pascal J. Bourguignon" pjb@informatimago.com wrote:
Alternatively, we could have:
(defsystem :foo :version-major 1 :version-minor 0 :version-release 42 :human-readable-version-string "1.0.gamma.XLII/pescadero:whasaaaaa")
or:
(defsystem :foo :version (1 0 42) :human-readable-version-string "1.0.gamma.XLII/pescadero:whasaaaaa")
Actually, I had something like that in mind. With this idea of allowing individual systems to handle their own versioning logic, I intended to put something like '(1 3 :beta 4 "Release Name") in the :version slot.
A human-readable version is different from a version specifier. ASDF already does something shaky in this regard, even for its simplistic versioning scheme: because it normalizes versions into strings, it needs to provide UNPARSE-VERSION! Yuck.
So if ASDF (or its users) insists on have human readable version strings, I wouldn't mind systems having both :version and :version-string.
On Tue, Jun 16, 2015 at 7:39 AM, Pascal J. Bourguignon pjb@informatimago.com wrote:
Didier Verna didier@lrde.epita.fr writes:
Hi,
in general, I don't like the way ASDF tries to force you to comply with its own design choices and policy. This is especially true for component versioning. ASDF complains that it doesn't like my version numbers (which, in fact, are not only numbers ;-), but I'm not ready to give up on them. They're much more informative than ASDF's simplistic 1.2.3.
Alternatively, we could have:
(defsystem :foo :version-major 1 :version-minor 0 :version-release 42 :human-readable-version-string "1.0.gamma.XLII/pescadero:whasaaaaa")
or:
(defsystem :foo :version (1 0 42) :human-readable-version-string "1.0.gamma.XLII/pescadero:whasaaaaa")
First, the restriction on version format comes straight out of ASDF 1, that itself lifted it from Linux .so "semantic versioning" — even to the point of declaring that a major number change makes things not compatible anymore, which was reverted in ASDF 3 for going against practice in the CL community in addition to breaking version compatibility for ASDF itself.
What I did with ASDF 2 then ASDF 3 was "just" to fix bugs, tweak the semantics as above, and make the restrictions explicit rather than fail silently when they aren't followed.
One constraint of ASDF 1 was to remain minimal, which explains the design. Let's just say that ASDF 3 was based on a different idea of what the spec was for ASDF to be minimal at implementing, and ended up 10 times bigger than ASDF 1. Would implementing, e.g. Debian or RedHat version comparison be possible? Sure, but, having implemented them (in a different project, see e.g. in lisp my rpm package), I can tell they are butt-ugly and not necessarily better than ASDF's algorithm in addition to not being as minimal.
I kind of like the general idea of Pascal's proposal: separate a human-readable-version-string from an asdf-comparable-version-string. The exact names are to be determined. Maybe, by analogy with name and long-name, description and long-description, we could make that version (used by ASDF) and long-version (used by humans).
In any case, this change won't happen before 3.2 (at least) and using it will have to be conditional on #+asdf3.2 until it becomes ubiquitous (estimated delay: 2 years after release). In the meantime, all code has to make do with what ASDF can handle, or do without asdf version at all (not recommended).
NB: To define new methods, you'd have to define a new system class first, with methods on it, in a defsystem-depends-on.
__Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk
This is a recycled old joke about airplane cockpits. I don't know how things go for factories, but in the case of airplanes, it also refers to the effects of regulations that force upon everyone antiquated unsafe technologies (i.e. human pilots) in the name of "safety" and actually as the result of protectionist lobbying.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Solipsism is a lonely place. Psychopaths crave love, but can't get no satisfaction: even elected by millions, it's still non-people voting for them.
Faré fahree@gmail.com wrote:
I kind of like the general idea of Pascal's proposal: separate a human-readable-version-string from an asdf-comparable-version-string. The exact names are to be determined. Maybe, by analogy with name and long-name, description and long-description, we could make that version (used by ASDF) and long-version (used by humans).
Works for me, as long as it is also possible to delegate comparison to the concerned system. Or, you adopt my personal versioning scheme :-D.
I would welcome a restructuring of the version comparison protocol along the lines that Didier suggests: make sure all the components of the protocol are properly handled by generic functions, and allow system developers and maintainers to manage their own version comparison logic should they so choose.
Now: a request for management purposes: Didier, would you be so kind as to describe the proposal (I think cut and paste out of your earlier emails would do admirably) in a ticket on launchpad.net?
Right now we are juggling altogether too many simultaneous suggestions for improvement that are candidates for 3.2. This has nothing to do with the many admirable suggestions, but rather has to do with issues getting 3.1.5 tested and debugged on Windows. Neither Faré nor I have the facilities to do this testing, so testing is slow, as is repairing bugs that arise.
I would like to be able to come back to improvements for 3.2 as soon as the Windows problems can be eliminated and 3.1.5 finally released.
Thank you, Robert
Robert Goldman rpgoldman@sift.net wrote:
Now: a request for management purposes: Didier, would you be so kind as to describe the proposal (I think cut and paste out of your earlier emails would do admirably) in a ticket on launchpad.net?
OK. I will also add Pascal's suggestion to have both a canonical and human readable version slot.
On 6/16/15 Jun 16 -9:31 AM, Didier Verna wrote:
Robert Goldman rpgoldman@sift.net wrote:
Now: a request for management purposes: Didier, would you be so kind as to describe the proposal (I think cut and paste out of your earlier emails would do admirably) in a ticket on launchpad.net?
OK. I will also add Pascal's suggestion to have both a canonical and human readable version slot.
I'm inclined to put that one on the side, mostly because I find Pascal's suggestion far less appealing. I see two problems with this suggestion:
1. Further complicating an ASDF that's already grown far larger than the original
2. Duplication of function. Software engineering is replete with failures where programmers are required to state the same information twice (e.g., comments or javadoc together with source code). Inevitably, the multiple forms of redundant information stray from each other. So what happens when the programmer updates the human readable version and not the canonical version, or vice versa? Wouldn't it be better to functionally derive one of these two forms from the other? E.g., (defgeneric formatted-version (component version-spec))
I am also disinclined to add something like the proposed
:version-major 1 :version-minor 0 :version-release 42
There are two reasons for my reluctance:
1. I don't think it's necessary. If those slots are desired, it should be possible to extend the SYSTEM class for specific systems in order to accommodate these new flags, without changing the core of ASDF.
If that's *not* true, then we should fix the protocols to make it true (and I'd welcome another ASDF ticket to this effect).
2. Adding this proliferation of version sub-flags to core ASDF seems undesirable for a number of reasons: * It would potentially radically complicate the parsing of systems. * Developers are already disinclined to put in :version specifiers: making the specification more complicated seems unlikely to improve that situation. * Adding more (and more verbose) flags would further detract from readability of DEFSYSTEM forms by burying their true content in ever more metadata. * Finally, I don't see that this provides advantage over :version "1.0.42" together with functions for manipulating said version string (e.g., (defgeneric major-version (component version-string) ).
In sum, this seems like a lot of new hair for limited payoff to the community.
Best, Robert
Robert Goldman rpgoldman@sift.net wrote:
So what happens when the programmer updates the human readable version and not the canonical version, or vice versa? Wouldn't it be better to functionally derive one of these two forms from the other? E.g., (defgeneric formatted-version (component version-spec))
Probably. The only advantage I see in PB's suggestion is for people actually reading the system definition's code. But then, don't do that. Use Declt to create the reference manual ;-)
I am also disinclined to add something like the proposed
+1
On 6/16/15 Jun 16 -10:24 AM, Didier Verna wrote:
Robert Goldman rpgoldman@sift.net wrote:
So what happens when the programmer updates the human readable version and not the canonical version, or vice versa? Wouldn't it be better to functionally derive one of these two forms from the other? E.g., (defgeneric formatted-version (component version-spec))
Probably. The only advantage I see in PB's suggestion is for people actually reading the system definition's code. But then, don't do that. Use Declt to create the reference manual ;-)
I am also disinclined to add something like the proposed
+1
Just to clarify: I am NOT saying Pascal is wrong to want these things or to do them himself. And I AM saying that ASDF should make it possible for him to do so.
I'm just saying I don't want them in the core of ASDF.
This is a matter of cost/benefit analysis for ASDF as a whole.
Cheers, R
Robert Goldman rpgoldman@sift.net wrote:
Just to clarify: I am NOT saying Pascal is wrong to want these things or to do them himself. And I AM saying that ASDF should make it possible for him to do so.
ASDF could call FORMATTED-VERSION itself to initialize the corresponding slot (if any), and refrain from providing a writer for it.
On 6/16/15 Jun 16 -10:33 AM, Didier Verna wrote:
Robert Goldman rpgoldman@sift.net wrote:
Just to clarify: I am NOT saying Pascal is wrong to want these things or to do them himself. And I AM saying that ASDF should make it possible for him to do so.
ASDF could call FORMATTED-VERSION itself to initialize the corresponding slot (if any), and refrain from providing a writer for it.
I suppose, but then calling FORMATTED-VERSION would just amount to memoizing the value of FORMATTED-VERSION into a slot on the ASDF system object. Why would that be a win over just calling FORMATTED-VERSION on demand?
I.e., we could just provide something like
(defgeneric FORMATTED-VERSION (C &optional version) (:method ((COMPONENT C) &optional version) (or version (component-version c)))
and then the programmer could extend this as needed.
cheers, r
Robert Goldman rpgoldman@sift.net wrote:
Why would that be a win over just calling FORMATTED-VERSION on demand?
I.e., we could just provide something like
(defgeneric FORMATTED-VERSION (C &optional version) (:method ((COMPONENT C) &optional version) (or version (component-version c)))
and then the programmer could extend this as needed.
You're right of course.
Robert Goldman rpgoldman@sift.net writes:
On 6/16/15 Jun 16 -9:31 AM, Didier Verna wrote:
Robert Goldman rpgoldman@sift.net wrote:
Now: a request for management purposes: Didier, would you be so kind as to describe the proposal (I think cut and paste out of your earlier emails would do admirably) in a ticket on launchpad.net?
OK. I will also add Pascal's suggestion to have both a canonical and human readable version slot.
I'm inclined to put that one on the side, mostly because I find Pascal's suggestion far less appealing. I see two problems with this suggestion:
- Further complicating an ASDF that's already grown far larger than the
original
- Duplication of function. Software engineering is replete with
failures where programmers are required to state the same information twice (e.g., comments or javadoc together with source code). Inevitably, the multiple forms of redundant information stray from each other. So what happens when the programmer updates the human readable version and not the canonical version, or vice versa? Wouldn't it be better to functionally derive one of these two forms from the other? E.g., (defgeneric formatted-version (component version-spec))
I am also disinclined to add something like the proposed
:version-major 1 :version-minor 0 :version-release 42
There are two reasons for my reluctance:
- I don't think it's necessary. If those slots are desired, it should
be possible to extend the SYSTEM class for specific systems in order to accommodate these new flags, without changing the core of ASDF.
If that's *not* true, then we should fix the protocols to make it true (and I'd welcome another ASDF ticket to this effect).
- Adding this proliferation of version sub-flags to core ASDF seems
undesirable for a number of reasons:
- It would potentially radically complicate the parsing of systems.
- Developers are already disinclined to put in :version specifiers:
making the specification more complicated seems unlikely to improve that situation.
- Adding more (and more verbose) flags would further detract from
readability of DEFSYSTEM forms by burying their true content in ever more metadata.
- Finally, I don't see that this provides advantage over :version
"1.0.42" together with functions for manipulating said version string (e.g., (defgeneric major-version (component version-string) ).
In sum, this seems like a lot of new hair for limited payoff to the community.
Agreed, spliting version is bad.
On the other hand, using a list of integer as version could be an improvement, since it would make it clear what a version is.
:version (1 0 42)
Of course, Didier already perverted the idea by writing something like:
:version (1 3 :beta 4 "Release Name")
In cesarum, I solved the problem with the heuristic of "parsing" and filtering out non-integers from the version strings, to obtain a normalized version number.
version ::= [a-z]* integer ('.' integer)* ('.' [a-z]+)? (+|[a-z]|'r' integer)? ('(' /.*/)?
cl-user> (use-package :com.informatimago.common-lisp.cesarum.version) t cl-user> (version (lisp-implementation-version)) (1 10 16196) cl-user> (version "1.10-r16196.beta.42.yosemite (x86) happy hacking.3") (1 10 16196) cl-user> (version "1.10.4") (1 10 4)
(mapcar (function version) '("1.3.1" "Version 1.10-r16196 (LinuxX8664)" "2.49+ (2010-07-17) (built 3603386203) (memory 3603386298)" "20d (20D Unicode)" "13.5.1" "1.0.57.0.debian")) --> '((1 3 1) (1 10 16196) (2 49 1) (20 3) (13 5 1) (1 0 57 0))
I kind of like the general idea of Pascal's proposal: separate a human-readable-version-string from an asdf-comparable-version-string. The exact names are to be determined. Maybe, by analogy with name and long-name, description and long-description, we could make that version (used by ASDF) and long-version (used by humans).
Works for me, as long as it is also possible to delegate comparison to the concerned system. Or, you adopt my personal versioning scheme :-D.
Versioning is a can of worms I refrained from opening while I was the maintainer, and that I'd rather keep not opening now that I'm not anymore. I don't know what Robert's position is, but I suppose the general ASDF policy is to accept patches, as long as (1) it's backward compatible (or there's a STRONG reason not to be AND there are only few affected users in Quicklisp, if any, who all have been notified and/or offered backward and forward compatibility patches), (2) it allows ASDF itself to remain minimal, and leaves advanced features to extensions, (3) the patch includes tests.
So, if you can implement you version scheme as an extension, ASDF will probably be happy providing all the hooks you need in ASDF 3.2, if they are currently missing -- but the hard work of determining whot those hooks are remains yours, and they can't be made to magically appear in old versions of ASDF, either.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Absent, adj.: Exposed to the attacks of friends and acquaintances; defamed; slandered.
Faré fahree@gmail.com writes:
“The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk
This is a recycled old joke about airplane cockpits. I don't know how things go for factories, but in the case of airplanes, it also refers to the effects of regulations that force upon everyone antiquated unsafe technologies (i.e. human pilots) in the name of "safety" and actually as the result of protectionist lobbying.
As the recent crash of GermanWings demonstrated. Perhaps they should start to bring dogs in cockpits.
If you need a pause, compare:
Amazon Robot Warehouse: https://www.youtube.com/watch?v=quWFjS3Ci7A
Human Warehouse: https://www.youtube.com/watch?v=KTnGZ37sZqM