Page 2 of 5 FirstFirst 1234 ... LastLast
Results 11 to 20 of 41

Thread: Cdecl (-> dll)

  1. #11
    Hello Rob and Charles,

    @Rob:

    1. Yes, C conditionals are always evaluated the "exclusive" (lazy) way, evaluation being stopped at the first occurrence of a condition that happens to be met. Traditional BASIC evaluation is "inclusive", i.e. it always checks the entire range of conditions specified, which is inefficient speed-wise and may cause bugs that are not evident and difficult to intercept. FBSL's BASIC has both strategies implemented natively while FBSL's ANSI C naturally supports lazy evaluation only.

    2. Thanks for the info on the Luminance HDR package. I once wrote a texture loader that was supposed to handle images stored in a Radiance HDR format (.RGB, .RGBE) and now I saw that "Luminance HDR" label. So I thought it might be something that I missed altogether but now I realize I was simply caught by this pun on words - Luminance and Radiance.

    @Charles:

    Yep, I guess cyclic wave audio would be too special to have it implemented at the core level. Nonetheless thanks for answering. (anyway I said "just curious..." )
    Mike
    (3.6GHz i5 Core Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, x64 Windows 7 Ultimate Sp1)

  2. #12
    Hi Mike,

    "inclusive" - maybe an "almost mistake" ? (and confusing imo)

    ----------------------------
    Uses "Console"

    Sub test(x As Integer) As Single
    If (x<>0) And (1/x < 1) Then test=Sqr(x)
    End Sub


    PrintL test(7)
    PrintL test(6)
    PrintL test(0)


    WaitKey
    --------------------------------------
    crashes of course -- here the reason is obvious, but it may be (very , very ) well hidden ....
    .. and on top of this , logically , we may think .. "but I excluded x=0 , what happened ?? "

    in Lisp the forcing into strict evalution may make a (very, very) little sense :
    after all, one can include something to catch the exception ...

    (when NaN? (print "Sorry, don't know how to handle this") (wait-for-human-help) )

    it will not crash .. it's even possible to define things as :

    inf + number = inf
    inf + inf = inf
    inf * inf = inf
    inf / inf = NaN (most of the time, there may be a solution -- needs human interaction )
    0 * inf = NaN etc ....

    after all it's a programmable programming language -- getting O/T oops ,

    best Rob
    Last edited by RobbeK; 03-05-2014 at 16:14.

  3. #13
    Rob,

    I'm using the words "inclusive"/"exclusive" here in the sense of the English set phrase "All inclusive": whatever conditions appear on one and the same code line (i.e. in one and the same expression) will be evaluated in their entirety.

    Such conditionals as If (x<>0) And (1/x < 1) Then test = Sqr(x) are perfectly valid and safe for a C compiler but are forbidden in a vanilla BASIC. You must use a nested If block to avoid division by 0 here:

    If x<>0 Then
    If 1/x<1 Then
    ...........


    The same concerns logical Or one-liners that may also generate similar pitfalls.

    FBSL's BASIC features And Also (aka AndAlso) and Or Else (aka OrElse) operators that act exactly like their "lazy" C counterparts and can be safely used in such one-liner conditionals as yours. Besides, while FPU division by zero is a legal operation in FBSL's BASIC that yields a + or -INF result depending on the sign of x, integer division by zero can be intercepted in the latest FBSL version with On Error GoTo/Resume Next error trapping.


    Regards,
    Last edited by mike lobanovsky; 04-05-2014 at 00:26. Reason: error trapping description added
    Mike
    (3.6GHz i5 Core Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, x64 Windows 7 Ultimate Sp1)

  4. #14
    Hé Mike,

    OOps , my excuses, it's not about any nomenclature nor any form of word choice -- the "almost mistake" is about using such a construction inside a programming language

    : (another try)
    .. using (all) inclusive evaluation of a sequence of conditions can (imo) be regarded as an almost mistake ...

    for the reason of equivalence between them , I put both within double quotes

    "inclusive" = "almost mistake" and not "inclusive" = almost mistake ...

    .. mea culpa (i'll skip the maxima ;-)

    best Rob

  5. #15
    Morning Rob,

    we may think .. "but I excluded x=0 , what happened ?? "
    Usually such pitfalls occur only when porting some "alien" code to BASIC the quick and dirty way. A predominantly BASIC oriented coder would tend to use nested Ifs even when coding in other languages. The "inclusive" behavior of BASIC one-liner conditionals was set forth by the ancient ECMA/ANSI/ISO/IEC standards and has been respected by all the three generations of BASIC ever since.

    Regards,
    Mike
    (3.6GHz i5 Core Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, x64 Windows 7 Ultimate Sp1)

  6. #16
    Hi Mike ,

    I don't think strict evalution has to be disadvantageous (from there the "almost" ) , be it that lazy eval can take advantage of infinite data structures (like in Haskell p.e. let numbers = [ 1,2 ... ] , one can write such things because it is not evaluated , you can map something on this sequence and then pick a certain element (or a sequence of elements ) only then calculations will start and they will scope a finite subset of the "numbers" ...

    This is Haskell or Scheme streams .. in Lisp calculations are strict , you have to build in a limit and work with countable data ..

    p.e. (apply '+ (map (lambda (x) (/ x)) (sequence 1 1000)))

    evaluated form right to left

    '(1 2 ... 1000) (Lisp builds the complete list)
    '(1 1/2 ... 1/1000)
    (+ 1 1/2 .... 1/1000)
    = Zeta(1) till 1000th term

    Makes me think building such a thing as the Glasgow Haskell compiler must be a kind of "tour de force".
    Another point is the lack of iteration mechanisms on those languages ... I don't like recursion at all (and in Scheme code I often see pseudo iterations a tail recursive [ (... n) ( (... (- n 1))) ] , I certainly prefer the Lisp do, dotimes, loop, for macro's (or the simple for ... next in Basic ).
    btw , the return stack in something NewLisp is that limited high amount recursion is impossible anyway ...

    I mean while lazy evaluation of conditions is one thing, lazy calculus may be another discussion point ?

    best, and thanks for ur reaction ! Rob

    (and in the end , things (lazy) may become what they say ;-) ... slow ... ( the overhead may increase significantly in deep nested calculations ... )
    Last edited by RobbeK; 04-05-2014 at 10:39.

  7. #17
    Good evening Rob,

    Quote Originally Posted by RobbeK View Post
    ...you can map something on this sequence and then pick a certain element (or a sequence of elements ) only then calculations will start and they will scope a finite subset of the "numbers" ...
    In FBSL, we also have dynamic Variant arrays, initialized or uninitialized, that can be redimensioned at run time very fast and can hold any data in any order and in any number since Variants are typeless. We can then apply an arbitrary routine to them using the Map(callback, array) function to process the array content in a specific task-dependent manner. Here callback is any user-defined function while array is the array (strong type static or Variant type dynamic) to process. I guess this functionality pretty much covers what you describe as Haskell-specific.

    ... evaluated form right to left
    Any manner of evaluation or transformation can be set forth in the custom callback function for use with a given array in a call to FBSL's Map().

    ...the Glasgow Haskell compiler must be a kind of "tour de force".
    Not in the least. It may have a more highly abstracted syntax with more things done behind the curtains but "how much do we want our data refined for us", as one very clever and talented FBSL user once asked me? Higher abstraction means lesser flexibility. We prefer to build our solutions from smaller Lego bricks to be in full control over what we're doing.

    I certainly prefer the Lisp do, dotimes, loop, for macro's (or the simple for ... next in Basic ).
    For/To/Step+/- is by no means simple. Modern BASIC's also feature Do While|Until/Loop While|Until, While/WEnd and Repeat/End Repeat blocks that pretty much cover all the above functionality. FBSL also has a For/DownTo/Step+/- loop, for that matter.

    ...the return stack in something NewLisp is that limited high amount recursion is impossible anyway ...
    I can change the Size of Stack Commit field in the PE header of my Fbsl.exe when compiling its sources with GCC. I'm pretty sure you can also hack the NewLisp (or thinBasic ) binary in a hex editor to increase the value written by the compiler into this field of PE header to make its (or their ) recursion capabilities as deep as you like. However, I would also recalculate the binary's Image Checksum in PE Explorer after such a hack and fix its value in the PE header too. This would preserve perfect integrity of the binary from the standpoint of Windows PE loader.

    I mean while lazy evaluation of conditions is one thing, lazy calculus may be another discussion point ?
    Exactly.


    Thanks again and have a nice night,
    Mike
    (3.6GHz i5 Core Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, x64 Windows 7 Ultimate Sp1)

  8. #18
    RobbeK,

    You can do something like this in Script BASIC.

    FUNCTION add(arg)
      add = arg + 1
    END FUNCTION
    
    value[0] = 10
    value[1] = 11
    value[2] = 12
    
    side1{"colors"}{"R"} = 128
    side1{"colors"}{"G"} = 64
    side1{"colors"}{"B"} = 32
    side1{"Title"}{"Top"} = "Top Title"
    side1{"Title"}{"Bottom"} = "Bottom Title"
    side1("Function"}{"add"} = ADDRESS(add())
    side1{"vertex"}{"values"} = value
    
    I think the perfect combo would be to embed Script BASIC in OyxgenBasic and use it for all your dynamic / typeless structures.

    Just a thought.
    ScriptBasic Project Manager
    Project Site
    support@scriptbasic.org

  9. #19
    Hi Mike,

    The more I hear about FBSL, the more interesting it sounds !!
    Abstraction, yes every abstraction hides information - on top, it may result in writing unnecessary code by sole reason of communication (protocol). On the other hand, it may come closer to human thinking patterns, the Haskell [ 1,2 ... ] is a good example -- we can "think" about an infinite sequence without calculating it -- however , were is the barrier (how far should it go) .. IIRC if you feed the GHC something as [ 2,4,6,8 ... ] it will expand it into something of the form 2N -- (does it more complex (non-linear extrapolation) too ??? - one should now if using this mechanism .. ).
    & then there are the endless benchmark competitions ... In the 1980s when working with Lisp, i've seen them many times ... "look my code runs as fast as C " ... yes, and when you looked at the code, it even looked like C ;-) (imo there is no intention (should be) for such things : Lisp == Lisp and C==C btw in that bot competition, the main part of the Haskell team were among the first to exit the arena ..; but then statistics prove everything and nothing (in France there are mor children born in regio with a lot of storks .. the conclusion is yours .. ;-)
    -- often statistics are used to link unrelated things , that's the trouble .. (politicians and such are rather strong into this ... )

    Hi John,
    Thanks !
    O2 is an excellent tool and language -- used it in the Lisp to interact with the Win GDI lib (and one very time-critical process (in the example attaced , about 10.000.000 iterations of the complex mapping z -> z²+c )) The input is done with Japi (uses Java) , but it was too slow for graphical high performance output (I couldn't find double buffered graphics in the documentation .. )

    thanks Rob


    oops ... edit : for Mike -- the most general iteration macro in Lisp ;-)

    -------------------------------------- (from the HyperSpecs -- as usual the "*" makes the difference between paralel and sequential assigment )

    Macro DO, DO*


    Syntax:


    do ({var | (var [init-form [step-form]])}*) (end-test-form result-form*) declaration* {tag | statement}*

    => result*


    do* ({var | (var [init-form [step-form]])}*) (end-test-form result-form*) declaration* {tag | statement}*

    => result*



    Arguments and Values:


    var---a symbol.

    init-form---a form.

    step-form---a form.

    end-test-form---a form.

    result-forms---an implicit progn.

    declaration---a declare expression; not evaluated.

    tag---a go tag; not evaluated.

    statement---a compound form; evaluated as described below.

    results---if a return or return-from form is executed, the values passed from that form; otherwise, the values returned by the result-forms.


    Description:


    do iterates over a group of statements while a test condition holds. do accepts an arbitrary number of iteration vars which are bound within the iteration and stepped in parallel. An initial value may be supplied for each iteration variable by use of an init-form. Step-forms may be used to specify how the vars should be updated on succeeding iterations through the loop. Step-forms may be used both to generate successive values or to accumulate results. If the end-test-form condition is met prior to an execution of the body, the iteration terminates. Tags label statements.

    do* is exactly like do except that the bindings and steppings of the vars are performed sequentially rather than in parallel.

    Before the first iteration, all the init-forms are evaluated, and each var is bound to the value of its respective init-form, if supplied. This is a binding, not an assignment; when the loop terminates, the old values of those variables will be restored. For do, all of the init-forms are evaluated before any var is bound. The init-forms can refer to the bindings of the vars visible before beginning execution of do. For do*, the first init-form is evaluated, then the first var is bound to that value, then the second init-form is evaluated, then the second var is bound, and so on; in general, the kth init-form can refer to the new binding of the jth var if j < k, and otherwise to the old binding of the jth var.

    At the beginning of each iteration, after processing the variables, the end-test-form is evaluated. If the result is false, execution proceeds with the body of the do (or do*) form. If the result is true, the result-forms are evaluated in order as an implicit progn, and then do or do* returns.

    At the beginning of each iteration other than the first, vars are updated as follows. All the step-forms, if supplied, are evaluated, from left to right, and the resulting values are assigned to the respective vars. Any var that has no associated step-form is not assigned to. For do, all the step-forms are evaluated before any var is updated; the assignment of values to vars is done in parallel, as if by psetq. Because all of the step-forms are evaluated before any of the vars are altered, a step-form when evaluated always has access to the old values of all the vars, even if other step-forms precede it. For do*, the first step-form is evaluated, then the value is assigned to the first var, then the second step-form is evaluated, then the value is assigned to the second var, and so on; the assignment of values to variables is done sequentially, as if by setq. For either do or do*, after the vars have been updated, the end-test-form is evaluated as described above, and the iteration continues.

    The remainder of the do (or do*) form constitutes an implicit tagbody. Tags may appear within the body of a do loop for use by go statements appearing in the body (but such go statements may not appear in the variable specifiers, the end-test-form, or the result-forms). When the end of a do body is reached, the next iteration cycle (beginning with the evaluation of step-forms) occurs.

    An implicit block named nil surrounds the entire do (or do*) form. A return statement may be used at any point to exit the loop immediately.

    Init-form is an initial value for the var with which it is associated. If init-form is omitted, the initial value of var is nil. If a declaration is supplied for a var, init-form must be consistent with the declaration.

    Declarations can appear at the beginning of a do (or do*) body. They apply to code in the do (or do*) body, to the bindings of the do (or do*) vars, to the step-forms, to the end-test-form, and to the result-forms.


    Examples:


    (do ((temp-one 1 (1+ temp-one))
    (temp-two 0 (1- temp-two)))
    ((> (- temp-one temp-two) 5) temp-one)) => 4

    (do ((temp-one 1 (1+ temp-one))
    (temp-two 0 (1+ temp-one)))
    ((= 3 temp-two) temp-one)) => 3

    (do* ((temp-one 1 (1+ temp-one))
    (temp-two 0 (1+ temp-one)))
    ((= 3 temp-two) temp-one)) => 2

    (do ((j 0 (+ j 1)))
    (nil) ;Do forever.
    (format t "~%Input ~D:" j)
    (let ((item (read)))
    (if (null item) (return) ;Process items until NIL seen.
    (format t "~&Output ~D: ~S" j item))))
    >> Input 0: banana
    >> Output 0: BANANA
    >> Input 1: (57 boxes)
    >> Output 1: (57 BOXES)
    >> Input 2: NIL
    => NIL

    (setq a-vector (vector 1 nil 3 nil))
    (do ((i 0 (+ i 1)) ;Sets every null element of a-vector to zero.
    (n (array-dimension a-vector 0)))
    ((= i n))
    (when (null (aref a-vector i))
    (setf (aref a-vector i) 0))) => NIL
    a-vector => #(1 0 3 0)


    (do ((x e (cdr x))
    (oldx x x))
    ((null x))
    body)

    is an example of parallel assignment to index variables. On the first iteration, the value of oldx is whatever value x had before the do was entered. On succeeding iterations, oldx contains the value that x had on the previous iteration.

    (do ((x foo (cdr x))
    (y bar (cdr y))
    (z '() (cons (f (car x) (car y)) z)))
    ((or (null x) (null y))
    (nreverse z)))

    does the same thing as (mapcar #'f foo bar). The step computation for z is an example of the fact that variables are stepped in parallel. Also, the body of the loop is empty.

    (defun list-reverse (list)
    (do ((x list (cdr x))
    (y '() (cons (car x) y)))
    ((endp x) y)))

    As an example of nested iterations, consider a data structure that is a list of conses. The car of each cons is a list of symbols, and the cdr of each cons is a list of equal length containing corresponding values. Such a data structure is similar to an association list, but is divided into ``frames''; the overall structure resembles a rib-cage. A lookup function on such a data structure might be:


    (defun ribcage-lookup (sym ribcage)
    (do ((r ribcage (cdr r)))
    ((null r) nil)
    (do ((s (caar r) (cdr s))
    (v (cdar r) (cdr v)))
    ((null s))
    (when (eq (car s) sym)
    (return-from ribcage-lookup (car v)))))) => RIBCAGE-LOOKUP


    Affected By: None.


    Exceptional Situations: None.

    ----------------------------------------------
    Attached Images Attached Images
    Last edited by RobbeK; 06-05-2014 at 14:11.

  10. #20
    Well, I've got the lazy-evaluation working better in OxygenBasic. The lazy leapfrog is confined to non-nested boolean expressions which contain comparators. For example:

    if (a>b) and (b<c) and (b<>b) then ...

    This is a very common pattern and in this case, Lazy takes the opportunity to jump at each and whenever the comparator expression yields false.


    I've also improved infinity and zero handling for floats:
    Signed infinity and zero are supported. Could be useful for atn()

    def infinity 1/0


    double d=infinity
    double e=-d
    print d
    '#INF
    print e
    '#-INF
    print 1/d ' 0
    print 1/-d '-0
    print atn d 'pi/2
    print atn e '-pi/2




    If the number cannot be valued, the FPU will oblige by returning #qNAN

    def nan 0/0


    double n=nan
    double m=n
    print m
    if m=n then print "invaluable!"



    thinBasic_Oxygen latest:
    http://www.thinbasic.com/community/showthread.php?12175



    PS: Stripping unused code from a program is rather similar to lazy computation. The compiler has to backtrace the code, starting at the top level, tag all the invoked functions, then delete all the others. A kind of pruning operation. So I wonder if this algorithm, in some form, could be applied to computation as well.
    In Oxygen, this mode is activated with #compact
    Last edited by Charles Pegge; 06-05-2014 at 19:24.

Page 2 of 5 FirstFirst 1234 ... LastLast

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •