Hi Julien, Good and interesting point. Your summary is correct: STON, inheriting from JSON so to speak, only knowns about integer and float numbers. All other Smalltalk numbers get converted, which results in a loss of type and precision. That might not be a perfect situation, but nobody complained so far. If we would change it, efficiency has to be taken into account: speed/memory efficiency as well as human typing efficiency/complexity. Compatibility, especially between different Smalltalk and other object languages, is also an aspect. Apart from the current approach, the full STON approach could be, for example for 1/3 and 1.5s2 Fraction { #numerator:1, #denominator:3 } ScaledDecimal { #numerator:3, #denominator:2, #scale:2} For some types, STON uses shorter notations, either using positional arguments Point [ 1, 2 ] Fraction [ 1, 3 ] ScaledFraction [ 3, 2, 2 ] Or a string argument, when there is a clear external representation DateAndTime [ '2018-09-18T16:39:10.325129+02:00' ] Fraction [ '1/3' ] ScaledFraction [ '3/2s2' ] Of course, we could also extend the basic number parser and allow the native (stored) notation 1/3 3/2s2 Note how that last one should use the more exact #storeOn: notation, not the #printOn: I'll have to think about this a bit more, as I can really not choose right now. Sven
On 18 Sep 2018, at 10:34, Julien <julien.delplanque@inria.fr> wrote:
Hello,
I realised that in the current implementation, when a number is serialised by STON it is either as an integer literal or as a float literal.
There is a risk to loose precision, especially if what you serialise is a ScaledDecimal or a fraction.
I propose a simple change to fix this:
1. Add STONWriter>>#isInJsonMode method which returns true if the STONWriter wants to write JSON
2. Add:
Fraction>>#stonOn: stonWriter stonWriter isInJsonMode ifTrue: [ ^ super stonOn: stonWriter ].
stonWriter writeObject: self streamMap: [ :dictionary | dictionary at: #numerator put: numerator. dictionary at: #denominator put: denominator ]
3. Add:
ScaledDecimal>>#stonOn: stonWriter stonWriter isInJsonMode ifTrue: [ ^ super stonOn: stonWriter ].
stonWriter writeObject: self streamMap: [ :dictionary | dictionary at: #numerator put: numerator. dictionary at: #denominator put: denominator. dictionary at: #scale put: scale ]
This change has a main drawback, storing fractions and scaled decimal will result in a huge overhead.
Maybe for ScaledDecimal we can use Pharoâs literal (e.g. 1.12s2).
For fractions I donât know what literal could be used?
Or maybe the overhead is fine?
Cheers,
Julien
--- Julien Delplanque Doctorant à lâUniversité de Lille http://juliendelplanque.be/phd.html Equipe Rmod, Inria Bâtiment B 40, Avenue Halley 59650 Villeneuve d'Ascq Numéro de téléphone: +333 59 35 86 40