Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Beginner's automatic type conversion

 [1/7] from: laurent::giroud::libertysurf::fr at: 23-Sep-2002 1:10


Hello everyone, I am still a beginner and would like to have some experts comments on Rebol code I managed to write recently. This is a very simple example but since all the reflexions on the list are always very insightful (at least to me !) I thought it could be a good thing to have my code criticized by people who know what they are talking about ;) What I am doing is very simple, I get string data and store it this way : trans: [ ["09:33" "12.30" "1 270"] ; [string! string! string!] ["09:34" "12.31" "4 450"] ... ] and need to convert it (for faster manipulation later on) into : [ [9:33 12.30 1270] ; [time! decimal! integer!] [9:34 12.31 4450] ... ] My original conversion code was : foreach t trans [ [change trans reduce to-time first trans to-decimal second trans to-integer trim/all third trans ] ] not very elegant but works fine ;) However, I thought that it would be more flexible to act as if I did not know in advance what the type of elements was. Since Rebol is already capable to guess the correct type for data it encounters within scripts or the console I thought that it was possible to find a way to have Rebol guess the correct type by itself. I went into much trouble to write a working solution but finally got this code to do the job : (beware line cuts) foreach t trans [ for i 1 length? t 1 [ do rejoin ["t/" i ": to-" type? do trim/all t/:i " " t/:i] ] ] it uses the 'do function to have rebol guess the correct type ("do t/:i") from the string then builds the code to convert the current element to its new value and executes this code using 'do again. This is very short but it took me almost three hours to write this :( I still struggle a lot to write code like this which executes statements it has itself generated and there seems to be so many ways to do the same thing in Rebol that I am never quite sure that I found a good one ;) So all comments will be more than welcome ! Best regards, Laurent -- Laurent Giroud [laurent--giroud--libertysurf--fr]

 [2/7] from: tomc:darkwing:uoregon at: 22-Sep-2002 16:42


'load may be what you are looking for foo: ["09:33" "12.30" "1 270"] == ["09:33" "12.30" "1 270"]
>> foreach f foo[append bar load trim/all f]
== [9:33 12.3 1270]
>> foreach b bar[ print type? b]
time decimal integer On Mon, 23 Sep 2002, Laurent Giroud wrote:

 [3/7] from: al:bri:xtra at: 23-Sep-2002 12:26


> However, I thought that it would be more flexible to act as if I did not
know in advance what the type of elements was. Best solution is to use 'load, which will translate the string into rebol values. I'd use something like: map/only Trans func [Block [block!]] [ map/only Block func [String [string!]] [ load String ] ] My 'Map function looks like (for the regulars, I've made one slight change): Rebol [ Name: 'Map Title: "Map" File: %"Map.r" Author: "Andrew Martin" eMail: [Al--Bri--xtra--co--nz] Web: http://valley.150m.com Date: 26/August/2002 Version: 1.1.0 Purpose: {Maps or applies the function to all elements of the series.} Category: [util 1] Acknowledgements: [ "Joel Neely" "Ladislav" ] Example: [ Map func [n [number!]] [n * n] [1 2 3] ;== [1 4 9] Map [1 2 3] func [n [number!]] [n * n] ;== [1 4 9] Map [1 2 3 4 5 6] func [a] [print [a]] ;1 ;2 ;3 ;4 ;5 ;6 ;== [] Map [1 2 3 4 5 6] func [a b] [print [a b]] ;1 2 ;3 4 ;5 6 ;== [] Map [1 2 3 4 5 6] func [a b c] [print [a b c]] ;1 2 3 ;4 5 6 ;== [] ] Requires: %Arguments.r ] Map: function [ {Maps or applies the function to all elements of the series.} Arg1 [any-function! series!] Arg2 [any-function! series!] /Only "Inserts the result of the function as a series." ][ Result Results Function Series ][ any [ all [ any-function? :Arg1 series? :Arg2 (Function: :Arg1 Series: :Arg2) ] all [ any-function? :Arg2 series? :Arg1 (Function: :Arg2 Series: :Arg1) ] throw make error! reduce [ 'script 'cannot-use rejoin [ {"} mold 'Map " " mold type? :Arg1 {"} ] rejoin [ {"} mold type? :Arg2 {"} ] ] ] Results: make Series length? Series do compose/deep [ foreach [(Arguments :Function)] Series [ if all [ not unset? set/any 'Result Function (Arguments :Function) not none? Result ] [ either only [ insert/only tail Results :Result ][ insert tail Results :Result ] ] ] ] Results ]
> I still struggle a lot to write code like this which executes statements > it has itself generated and there seems to be so many ways to do the same
thing
> in Rebol that I am never quite sure that I found a good one ;)
Have a look at the lines after: do compose/deep [ I hope that helps! Andrew Martin ICQ: 26227169 http://valley.150m.com/

 [4/7] from: g:santilli:tiscalinet:it at: 23-Sep-2002 11:07


Hi Laurent, On Monday, September 23, 2002, 1:10:00 AM, you wrote: LG> However, I thought that it would be more flexible to act as if I did not know in LG> advance what the type of elements was. What about: foreach t trans [ forall t [ t/1: load trim/all t/1 ] ] HTH, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [5/7] from: joel:neely:fedex at: 23-Sep-2002 6:29


Hi, Laurent, Whenever possible, I suggest letting REBOL do the work for you... See below. Laurent Giroud wrote:
> What I am doing is very simple, I get string data and store it > this way :
<<quoted lines omitted: 9>>
> ... > ]
The only tricky bit is the embedded space in the third element of each triplet, but you already know how to deal with that!
>> trans: [
[ ["09:33" "12.30" "1 270"] ; [string! string! string!] [ ["09:34" "12.31" "4 450"]] == [ ["09:33" "12.30" "1 270"] ["09:34" "12.31" "4 450"]] Using the first two triplets of your sample data...
>> foreach row trans [
[ foreach item row [ [ foo: load trim/all copy item [ print [item foo type? foo] [ ] [ ] 09:33 9:33 time 12.30 12.3 decimal 1 270 1270 integer 09:34 9:34 time 12.31 12.31 decimal 4 450 4450 integer Unless the input uses some strange representation (e.g., embedded spaces which must be removed) the REBOL lexical scanner will recognize the data for you. -jn- -- ; Joel Neely joeldotneelyatfedexdotcom REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] { | e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]

 [6/7] from: laurent:giroud:libertysurf at: 24-Sep-2002 22:05


Monday, September 23, 2002, 2:26:53 AM, Andrew Martin wrote :
>> However, I thought that it would be more flexible to act as if I did not > know in advance what the type of elements was. > Best solution is to use 'load, which will translate the string into rebol > values.
Many thanks you for your answers ! I was thinking that there would be a completely different solution so I'm quite glad to have found a not-so-bad one ;) I had not thought to use 'load since I did not grasp exactly (although my first message on the list was about a 'load related problem...) what it was doing. Now as I understand it, it translates data to rebol internal format, simplifying string values to the closest data types who match but does not evaluate them. So I presume that 'do internally calls 'load to convert raw data to rebol form before actually evaluating it, is that right ? Regards, Laurent -- Laurent Giroud [laurent--giroud--libertysurf--fr]

 [7/7] from: al:bri:xtra at: 25-Sep-2002 10:11


Laurent wrote:
> Now as I understand it, it translates data to rebol internal format,
simplifying string values to the closest data types who match but does not evaluate them. So I presume that 'do internally calls 'load to convert raw data to rebol form before actually evaluating it, is that right ? I'm about 99% certain that's correct. Andrew Martin ICQ: 26227169 http://valley.150m.com/

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted