| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#121
| |||
| |||
| m. Th. schrieb: > > procedure X(aDateTime: TDateTime); > begin > Result:=aDateTime-42; //whatever > end; > > and we do > > foo:=iif(y<>0, lambda x,y | Result:=x(GetActualDateTimeFromNASA)/y, > lambda Result:=0); > > The GetActualDateTimeFromNASA will get evaluated /regardless/ of the > value of 'y'. Is it? Let's see what a lambda abstraction really means: lambda x, y | Result := x(GetActualDateTimeFromNASA) / y I'm not an expert of functional programming, but it should be expanded into this: function (x, y: TDateTime): TDateTime; { The "x" here is different to your procedure X and the compiler wouldn't be able to determine it's type correctly since it is never used inside the function. That get's us back to type inference BTW. ;-) } begin // This results into a syntax error Result := x(GetActualDateTimeFromNASA) / y; end; What you really want is: lambda y | Result := X(GetActualDateTimeFromNASA) / y; which is expanded into: function(y: TDateTime): TDateTime; begin Result := X(GetActualDateTimeFromNASA) / y; end; Everything here works as expected, X is evaluated delayed when the condition is true. > > About your criticism wrt 'delay'. Yes, of course, one cannot 'see' > from the calling code. Ie. from iif(y<>0, x/y, 0) you cannot 'see' it. > In fact is /exactly/ the same situation now. Do you see if an argument > is 'var'? Or 'const'? You have to look at proc declaration. Same here. That's right, but there is a vary good reason for the 'var' keyword: It spares us from all the pointer stuff you have to do in C to pass arguments by reference. I try to avoid 'var' at all costs in my programs. Since objects are automatically passed around as pointers, 'var' is only necessary for basic types (Integer, string, etc.) > But with Code Insight support it won't be a problem. And more, imho, > not 'seeing' a 'var' it's a bigger problem (data overwrite) compared > with a 'delay' which in most cases is an optimization (ie. the > 'unnecessary' argument isn't evaluated). Don't forget the side effects. |
|
#122
| |||
| |||
| Jens Mühlenhoff schrieb: >> foo:=iif(y<>0, lambda x,y | Result:=x(GetActualDateTimeFromNASA)/y, >> lambda Result:=0); >> >> The GetActualDateTimeFromNASA will get evaluated /regardless/ of the >> value of 'y'. > > > function(y: TDateTime): TDateTime; > begin > Result := X(GetActualDateTimeFromNASA) / y; > end; > > Everything here works as expected, X is evaluated delayed when the > condition is true. > .... as is GetActualDateTimeFromNASA which was my point. |
|
#123
| |||
| |||
| Pieter, | Any error messages? Yes. "Declaration of TfmMain is missing or incorrect." | Try to do a "build all projects" (under the project menu). I did that... a couple of times. Also tried building packages one-by-one in the group project sequence. Same error on trying to build or compile Newsreader3. I also blew-away all of the .bpl files and re-downloaded from TechTips. Same-o, same-o. -- Q 08/04/2008 08:12:00 XanaNews Version 1.18.1.11 [Leonel's & Q's Mods] |
|
#124
| |||
| |||
| Jens Mühlenhoff schrieb: > Jens Mühlenhoff wrote: > >>> >>> >>> procedure Test; >>> var >>> I: Integer; >>> begin >>> I := iif( X = Y >> , function: Integer >>> begin >>> Result := ComplexExpression1 >>> end >> , function: Integer >>> begin >>> Result := ComplexExpression2 >>> end >>> ); >>> end; >> > > I thought some more: Now if we had lambda expressions this could even be > shortened to: > > I := iif(X = Y, \a -> ComplexExpression1, \a -> ComplexExpression2); > I read a bit more on the topic of "lambda" and it turns out the above isn't correct, it should be something like this (now also using the 'lambda' keyword: I := iff(X = Y, lambda | ComplexExpression1, lambda | ComplexExpression2); I don't know if a lambda abstraction with zero arguments is correct, it seems that a lambda abstractions needs exactly one variable and anonymous functions with more then one argument are defined using currying: lambda x, y | x * y <=> lambda x | (lamba y | x * y) Maybe someone with a more "functional" background can enligthen me? |
|
#125
| |||
| |||
| Jens Mühlenhoff wrote: > I don't know if a lambda abstraction with zero arguments is correct, In the lambda calculus, a function with zero arguments is a constant. Since there are no side effects and the result depends entirely on the arguments, no arguments means a constant result. Sometimes these are called free variables. > it seems that a lambda abstractions needs exactly one variable and > anonymous functions with more then one argument are defined using > currying: > > lambda x, y | x * y <=> lambda x | (lamba y | x * y) > > Maybe someone with a more "functional" background can enligthen me? You want to define: \Boolean -> \(T->U) In other words, you want a function which accepts a Boolean argument used as a predicate to select another function which takes an argument of type T and returns a result of type U. In the lambda calculus, there are only two possible results from this function, since a Boolean has only two possible values (not counting _|_, which is roughly the lambda calculus equivalent of throwing an exception). -- Craig Stuntz [TeamB] · Vertex Systems Corp. · Columbus, OH Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz Useful articles about InterBase development: http://blogs.teamb.com/craigstuntz/category/21.aspx |
|
#126
| |||
| |||
| Q Correll wrote: > Pieter, > > > Any error messages? > > Yes. "Declaration of TfmMain is missing or incorrect." > > > Try to do a "build all projects" (under the project menu). > > I did that... a couple of times. Also tried building packages > one-by-one in the group project sequence. Same error on trying to > build or compile Newsreader3. I also blew-away all of the .bpl files > and re-downloaded from TechTips. Same-o, same-o. Hm, strange. Just to be sure I created a new folder and checked out everything from SVN and did a Build all Projects, no problems here. Looks like your local copy is corrupted either the mainform.dfm or pas file. -- Pieter |
|
#127
| |||
| |||
| Pieter, | Looks like your local copy is corrupted either the mainform.dfm or pas Yep. I blew away everything, including the directory structure and re-D/L'd the project from TechTips. Then did a build-all from the GroupProj file and all went smoothly as expected. I must have had a corrupt D/L the first time. -- Q 08/04/2008 12:13:32 XanaNews Version 1.18.1.11 [Leonel's & Q's Mods] |
|
#128
| |||
| |||
| Jens Mühlenhoff wrote: > m. Th. wrote: > > > > function iif(aCondition: boolean; lazy aTrue: string; lazy aFalse: > > string): string; overload; > > > > Since we have Generics and anonymous types now, something like this > could be done: > > type > TEval<T> = reference to function: <T>; > > function iif<T>(aCond: boolean; aTrue: TEval<T>; aFalse: TEval<T>): T; > begin > if aCond then > Result := aTrue; > else > Result := aFalse; > end; > > > procedure Test; > var > I: Integer; > begin > I := iif( X = Y > , function: TEval<Integer> > begin > Result := ComplexExpression1 > end > , function: TEval<Integer> > begin > Result := ComplexExpression2 > end > ); > end; Syntactically, that doesn't quite look good, but the idea is fine: type TEval<T> = reference to function: T; function SomeClass.iif<T>(aCond: Boolean; aTrue, aFalse: TEval<T>): T; begin if aCond then Result := aTrue() else Result := aFalse(); end; procedure Test; var I: Integer; begin I := iif(X = Y, function: Integer begin Result := ComplexExpression1; end, function: Integer begin Result := ComplexExpression2; end); end; But I'm not sure if there would be any syntactical advantage in doing that. This is much simpler: if X = Y then I := ComplexExpression1 else I := ComplexExpression2; Now, if you'd have multiple iif() in, say, a function call, it might get very hard to follow, and therefore not very maintainable. In that case, I'd rather use a few extra variabels to hold the intermediate results and then do the call. -- Rudy Velthuis [TeamB] http://www.teamb.com "The object of war is not to die for your country but to make the other bastard die for his." -- General George Patton (1885-1945) |
|
#129
| |||
| |||
| Rudy Velthuis [TeamB] schrieb: > > Syntactically, that doesn't quite look good, but the idea is fine: I thought so *g*. > > But I'm not sure if there would be any syntactical advantage in doing > that. This is much simpler: > > if X = Y then > I := ComplexExpression1 > else > I := ComplexExpression2; > > Now, if you'd have multiple iif() in, say, a function call, it might > get very hard to follow, and therefore not very maintainable. In that > case, I'd rather use a few extra variabels to hold the intermediate > results and then do the call. What we really want here is either this: I := iif(X = Y, ComplexExpression1, ComplexExpression2); or at least this: I := iif(X = Y, anon ComplexExpression1, anon ComplexExpression2); where 'anon' makes it easier to use anonymous functions. You save 3 lines of code, of course if the 'ComplexExpressionX' is to long, it would be better to split it up somehow. I'm sure you know how easily this is done in C++: i = X == Y ? ComplexExpression1 : ComplexExpression2; Aside from the usual 'symbolic chaos' in C-like languages, I think 'iif' is a very good idea. |
|
#130
| |||
| |||
| Craig Stuntz [TeamB] schrieb: > Jens Mühlenhoff wrote: > >> I don't know if a lambda abstraction with zero arguments is correct, > > In the lambda calculus, a function with zero arguments is a constant. > Since there are no side effects and the result depends entirely on the > arguments, no arguments means a constant result. > > Sometimes these are called free variables. > Thanks for this explanation. I think we are not after the lambda calculus after all here, because in functional programming languages functions don't have side-effects and Pascal functions can have side-effects. So it's not 'lambda ComplexExpression1', but rather 'anon ComplexExpression' which is a shorthand for writing out: function: Integer; begin Result := ComplexExpression1; end; The biggest problem here: The compiler needs to infer the function definition (return type, function arguments, etc.). |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.