From: Barton W. <wi...@un...> - 2024-05-21 15:18:31
|
Tiny comment: The variables newvert and s_len are global. Likely you would like to declare them in a block? --Barton ________________________________ From: Stavros Macrakis <mac...@gm...> Sent: Tuesday, May 21, 2024 09:50 To: Justin Smith <jus...@gm...> Cc: max...@li... <max...@li...> Subject: Re: [Maxima-discuss] Nested functions Caution: Non-NU Email There is nothing wrong with defining a function within a function. However, it is not like a nested function in most other languages, which have lexical scope. First of all, the function definition will be global even if it's defined within another function. f(x):=(g(y):=23+y, g(40))$ f(12) => 63 g(5) => 28 << function is defined globally You can make it local by using the local pseudo-function. f(x):=(local(g), g(y):=23+y, g(40))$ f(12) => 52 g(5) => g(5) << function is not defined globally Secondly, since Maxima uses dynamic scope, the inner function does not share the containing functions variables statically, but dynamically. f(x):=( g(y):=x+y, [g(10), block([x:100], g(10) )] ) f(3) => [13, 110] <<< with static scope, you'd get [13, 13] This also means that if you return the function, it won't "see" the statically bound variables: f(x):= lambda([y], x+y)$ f(3)(5) => x+5 <<< with static scope, you'd get 8 So basically there is no particular reason to nest the function. It will probably be easier to read if it is not nested -- generally short functions are easier to read than long. For that matter, your code in general will be easier to read if it is indented systematically, something like this: euler_path(mgr, vert): = block([sofar: [], n_edges: cardinality(mgr@E), temp: [], forbidden: {}], partial_path(mgr, vert): = block([x, keepgoing: true, retval: []], vertices: mgr@V, for x in mgr@E while keepgoing do if not elementp(first(x), forbidden) and elementp(vert, last(x)) then block([newvert: first(listify(disjoin(vert, last(x)))), val], forbidden: adjoin(first(x), forbidden), keepgoing: false, val: partial_path(mgr, newvert), retval: append([vert, first(x)], val)), retval), sofar: partial_path(mgr, vert), while cardinality(forbidden) < n_edges do (for i step 2 thru length(sofar)-1 do (newvert: sofar[i], temp: partial_path(mgr, newvert), s_len: length(sofar), if length(temp) > 0 then sofar: append(firstn(sofar, i-1), temp, lastn(sofar, s_len-i+1)), temp: [])), sofar)$ On Tue, May 21, 2024 at 8:27 AM Justin Smith <jus...@gm...<mailto:jus...@gm...>> wrote: I have coded a nested function that appears to work properly. Is there anything wrong with this? defstruct(mgraph(V, E)); eulersberg: new(mgraph({A,B,C,D,E,F}, {[a,{E,F}], [b,{B,F}], [c,{B,F}], [d,{A,F}], [e,{A,F}], [f,{C,F}], [g,{A,C}], [h,{A,C}], [i,{C,D}], [k,{A,D}], [m,{A,E}], [n,{A,E}], [o,{B,E}], [p,{A,B}] })); euler_path(mgr,vert) := block( [sofar:[],n_edges:cardinality(mgr@E),temp:[], forbidden:{}], partial_path(mgr,vert):=block( [x,keepgoing:true,retval:[]], vertices:mgr@V, for x in mgr@E while (keepgoing) do ( if (not((elementp(first(x), forbidden) )) and elementp(vert, last(x))) then (block ( [newvert:first(listify(disjoin(vert, last(x)))), /* vertex at end of current edge */ val], forbidden:adjoin(first(x),forbidden), /* Put the current edge in forbidden */ keepgoing:false, /* Stop for-loop after an edge located */ val:partial_path(mgr,newvert), /* Continue the search with the rest of the graph */ retval:append( [vert,first(x)],val)) ) ), retval /* Return with this value */ ), sofar:partial_path(mgr,vert), while (cardinality(forbidden)<n_edges) do ( for i:1 step 2 thru length(sofar)-1 do ( newvert:sofar[i], temp:partial_path(mgr,newvert), s_len:length(sofar), if(length(temp)>0) then (sofar:append(firstn(sofar,i-1),temp,lastn(sofar,s_len-i+1))), temp:[] ) ), sofar ); q:euler_path(eulersberg,F); [F,a,E,n,A,h,C,i,D,k,A,p,B,o,E,m,A,d,F,b,B,c,F,e,A,g,C,f] -- "As long as you are not aware of the continual law of Die and Be Again, you are merely a vague guest on a dark Earth." --- Johann Wolfgang von Goethe Homepage: http://www.five-dimensions.org _______________________________________________ Maxima-discuss mailing list Max...@li...<mailto:Max...@li...> https://lists.sourceforge.net/lists/listinfo/maxima-discuss |