working with multiple return values
In Clojure, what is the easiest (cleanest) way to return multiple values from a function, in order to work with them immediately afterwards? In Haskell you can return a tuple, and pattern match the components into variables. Prelude let (a, b) = (1 + 4, 2 - 1) Prelude a 5 Prelude b 1 IIRC, Python has something similar. I know how to return a list or a vector, of course, but I'm imagining having to put in a bunch of cludgy code to extract the components into variables, which is not appealing. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: working with multiple return values
You can use destructuring user= (let [[a b] [(+ 1 2) (+ 2 3)]] [a b]) [3 5] Christopher Howard writes: In Clojure, what is the easiest (cleanest) way to return multiple values from a function, in order to work with them immediately afterwards? In Haskell you can return a tuple, and pattern match the components into variables. Prelude let (a, b) = (1 + 4, 2 - 1) Prelude a 5 Prelude b 1 IIRC, Python has something similar. I know how to return a list or a vector, of course, but I'm imagining having to put in a bunch of cludgy code to extract the components into variables, which is not appealing. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: accessing multiple return values
This is a really neat macro, but would people want to rewrite their programs in continuation-passing style just to be able to return multiple values sometimes? (And a macro is not a first-class entity.) Of course, much of the time, the easiest thing to do \is to return a vector or some other destructureable object. But this changes the interface: the function no longer directly returns a singular value. Metadata avoids this problem, but doesn't work on numbers, among other things. So there really are cases where having multiple return values would help (when you want a function to give you one value unless you want more)preferably without judo! (altough judo is great too.) Replying to Tassilo: I'm not quite sure I understand this problem: then changing its name requires changing all places where clojure.core.quotient/remainder is used surely the call to Values takes place inside the function definition, which happens \once. If you want a different variable name on \use, you use a let; if you want to return a different variable name on \definition, you use a let inside the function (or perhaps Values could have some sugar for renaming variables). It's true that quotient/remainder must be thread-local (in fact it should really be function-local), but this makes it no different than a let-variable or a function parameter; it doesn't necessarily mean it is mutable. Is X mutable in (let [X 1 X (inc X)]) ? If you slapped that X in a data structure, you would not find it changing under your nose. quotient/remainder really has to behave in the same wayimagine the quotient call creates an invisible let every time. Perhaps I should explain why I think this is simple. It's simple because a) it allows you to ignore the extra values unless you want them and b) it gives you ready-to-use names. To my taste, b) is very important. One of the reasons I dislike OOP is all the boilerplate like this.x = x. But how many times do you have to write (let [x (some-expensive function ... )] just so you can use the returned value more than once? What we would do here is write some-expensive-function/ the next time we want to use the value (assuming this is the notation for getting the \default value)so in this case we don't even \care about multiple return values. If we think of this as a name-generating facility that happens to handle multiple values, we could imagine extensions to it for distinguishing more values (quotient 5 2) (quotient 8 3) quotient(5 2)/remainder -- 1 (rand(1) 12) (rand(2) 12) rand(1)(12)/ This is all rather fanciful, and admittedly a huge extension to the language; but what's the harm in thinking about these things? The next time you are telling your kids a bedtime story, you might start as follows: A man ate some soup. The man was bald, and the soup had an unhappy grasshopper in it. The grasshopper Scratch that: you should tell it as follows: Let there be a man my-man, and some soup my-soup, and a grasshopper my- grasshopper. my-man ate some of my-soup. my-man was bald. my-soup had my-grasshopper in it. And my-grasshopper was unhappy This makes for earlier bedtimes but worse storytelling. On Jan 3, 12:36 am, Cedric Greevey cgree...@gmail.com wrote: On Mon, Jan 2, 2012 at 2:16 PM, Tassilo Horn tass...@member.fsf.org wrote: nchurch nchubr...@gmail.com writes: Hi, Someone was asking on the list here about multiple return values, which Clojure does not have. If the facility were ever added, perhaps multiple values could be accessed via namespaces. Functions would possess another level of namespace and have the ability to inject values into the environment under that namespace. For instance: (defn quotient [x y] . (values quotient remainder)) (clojure.core/quotient 5 2) -- 2 clojure.core/quotient/remainder -- 1 This seems simpler than the Common Lisp way. I don't think so. And there are several major problems with that approach. First of all, your clojure.core.quotient/remainder var needs to be a mutable, thread-local var, because else you couldn't be sure that 1 is the remainder of the quotient call directly above, or the remainder of a call that happened a blink later in another thread (or ForkJoinTask). Another problem is that if the var name is determined by the name of the local var in the function which is given to `values', then changing its name requires changing all places where clojure.core.quotient/remainder is used. On top of all that, how often is this needed anyway where destructuring or metadata can't solve the problem? When performance isn't a concern and you control the calling functions (or they're generic things like map and reduce that just pass the return value through to code you control, such as whatever processes the map sequence output) you can replace something with a vector of that something and additional values
Re: accessing multiple return values
nchurch nchubr...@gmail.com writes: Replying to Tassilo: I'm not quite sure I understand this problem: then changing its name requires changing all places where clojure.core.quotient/remainder is used surely the call to Values takes place inside the function definition, which happens \once. If you want a different variable name on \use, you use a let; if you want to return a different variable name on \definition, you use a let inside the function (or perhaps Values could have some sugar for renaming variables). I understand your proposal in such a way, that in a function (defn foo [x] (let [double-x (* 2 x)] (values x double-x))) the `values' was actually a macro that 1. creates a namespace for the function (user.foo) 2. creates a var holding the last second value (user.foo/double-x) where the name of the var is dictated by the local var holding the value 3. expands into code that sets user.foo/double-x at runtime and then returns the first value x Then, if I want to use the second value returned by foo in my code, I'd so something like (let [x (foo 17), dx user.foo/double-x] (do-something-with x dx)) Since I have to refer to user.foo/double-x to get the second value, once that name changes, I have to change my code, too. But probably, I've simply misunderstood your intent. It's true that quotient/remainder must be thread-local (in fact it should really be function-local), but this makes it no different than a let-variable or a function parameter; it doesn't necessarily mean it is mutable. Is X mutable in (let [X 1 X (inc X)]) ? Nope, the latter X shadows the former X. But there's no such thing for vars in a namespace. If you slapped that X in a data structure, you would not find it changing under your nose. quotient/remainder really has to behave in the same wayimagine the quotient call creates an invisible let every time. Sorry, I don't get you. What am I misinterpreting in your approach? To me, it looks like you want to bind the multiple values to vars in an ad-hoc namespace corresponding to a function. Then, there's no such thing as a lexical scope provided by let. A namespace is a globally accessible thingy. Perhaps I should explain why I think this is simple. It's simple because a) it allows you to ignore the extra values unless you want them and Well, the Common Lisp approach does so, too. b) it gives you ready-to-use names. To my taste, b) is very important. To me, that's a major downside. (quotient 5 2) (quotient 8 3) quotient(5 2)/remainder -- 1 Huh, you want to create a namespace not only for each function but for each function call? And then store the multiple values for each of them? Bye, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: accessing multiple return values
You're quite correct that the namespace \mechanism as it stands would not work for thisgood point. I guess I am just suggesting using the \syntax to do something let-like. Perhaps it would be better to make up a completely different syntax. As for your example, I'm still not sure we understand each other: (let [x (foo 17), dx foo/double-x] (do-something-with x dx)) Yes, that is how it would \look (I've dropped the user. as it isn't needed here). But why is the \name user.foo/double-x changing? It is dictated in the definition of foo, which is not itself changing. And (keeping in mind what I said above) once you refer to the \value in this way, it does not change. Later uses of foo should indeed \shadow this usage, not \change it. At any rate, it would be better to describe these as names within a function execution's \scope, not a function \namespace. Hopefully that is less confusing. As for storing values: as I said they should be \function-local, so that in (defn bar [...] (foo ...) (+ foo/double-x ...) ) foo/double-x expires after bar returns. On Jan 3, 2:15 pm, Tassilo Horn tass...@member.fsf.org wrote: nchurch nchubr...@gmail.com writes: Replying to Tassilo: I'm not quite sure I understand this problem: then changing its name requires changing all places where clojure.core.quotient/remainder is used surely the call to Values takes place inside the function definition, which happens \once. If you want a different variable name on \use, you use a let; if you want to return a different variable name on \definition, you use a let inside the function (or perhaps Values could have some sugar for renaming variables). I understand your proposal in such a way, that in a function (defn foo [x] (let [double-x (* 2 x)] (values x double-x))) the `values' was actually a macro that 1. creates a namespace for the function (user.foo) 2. creates a var holding the last second value (user.foo/double-x) where the name of the var is dictated by the local var holding the value 3. expands into code that sets user.foo/double-x at runtime and then returns the first value x Then, if I want to use the second value returned by foo in my code, I'd so something like (let [x (foo 17), dx user.foo/double-x] (do-something-with x dx)) Since I have to refer to user.foo/double-x to get the second value, once that name changes, I have to change my code, too. But probably, I've simply misunderstood your intent. It's true that quotient/remainder must be thread-local (in fact it should really be function-local), but this makes it no different than a let-variable or a function parameter; it doesn't necessarily mean it is mutable. Is X mutable in (let [X 1 X (inc X)]) ? Nope, the latter X shadows the former X. But there's no such thing for vars in a namespace. If you slapped that X in a data structure, you would not find it changing under your nose. quotient/remainder really has to behave in the same wayimagine the quotient call creates an invisible let every time. Sorry, I don't get you. What am I misinterpreting in your approach? To me, it looks like you want to bind the multiple values to vars in an ad-hoc namespace corresponding to a function. Then, there's no such thing as a lexical scope provided by let. A namespace is a globally accessible thingy. Perhaps I should explain why I think this is simple. It's simple because a) it allows you to ignore the extra values unless you want them and Well, the Common Lisp approach does so, too. b) it gives you ready-to-use names. To my taste, b) is very important. To me, that's a major downside. (quotient 5 2) (quotient 8 3) quotient(5 2)/remainder -- 1 Huh, you want to create a namespace not only for each function but for each function call? And then store the multiple values for each of them? Bye, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: accessing multiple return values
nchurch nchubr...@gmail.com writes: You're quite correct that the namespace \mechanism as it stands would not work for thisgood point. I guess I am just suggesting using the \syntax to do something let-like. Perhaps it would be better to make up a completely different syntax. As for your example, I'm still not sure we understand each other: (let [x (foo 17), dx foo/double-x] (do-something-with x dx)) Yes, that is how it would \look (I've dropped the user. as it isn't needed here). But why is the \name user.foo/double-x changing? Because the developer of the library refactored the foo function and thereby changed the local double-x to double-value. Library developers usually refrain from renaming functions, but the internals of a function itself shouldn't be of any interest to users. At any rate, it would be better to describe these as names within a function execution's \scope, not a function \namespace. Hopefully that is less confusing. As for storing values: as I said they should be \function-local, so that in (defn bar [...] (foo ...) ;; 1 (bar ...) ;; 2 (+ foo/double-x ...) ) foo/double-x expires after bar returns. What if bar is recursive like above. What's the value of foo/double-x in that case? The value of the call in line 1, or the value from the last foo in the recursive call in 2? I think, I'll stop here. You won't convince me that this approach is practicable anytime soon. ;-) Bye, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: accessing multiple return values
I think, I'll stop here. You won't convince me that this approach is practicable anytime soon. ;-) I certainly won't try too hard either. I'm not questioning here whether it is immediately practicable to implement (maybe not, and in case a very long discussion) but is it potentially useful? (A shorter discussion.) In answer to your questions: The name of a returned value, of course, \does become part of the interface. Perhaps library writers would want to have a discipline of using their own internal names and then passing them out in one final values call inside of a let. As to the second: the recursive (bar ...) call has no effect on any foo-values used outside of it, whether before or after. This accords with our expectation for how functions work. Think of Values as a magical macro that \at \runtime reaches outside of the function it was used in and writes a little let inside the calling function's scope. Is this possible? I don't think so. Presumably it would have to be part of the language, just like Values is part of Common Lisp. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: accessing multiple return values
I see two fairly straightforward paths to simulating multiple returns without breaking existing callers. Both take advantage of thread-local state and establish one convention for the caller: before calling the function again, every caller interested the extra return values must ask for these extra returned values before calling the function again. 1. Use and Abuse VarsThe multiple return idea sounds a lot like the global errno facility used commonly in C to communicate out of band errors that cannot be conveniently conveyed via the function's actually return, except with namespacing to help multiple functions cooperate for the scarce resources. That bit of magic can be pretty nasty and metadata usually solves the majority of cases needed to move that auxiliary information (errno changed from a simple global variable to a complicated macro with the advent of multi-threaded C applications). However, in cases that metadata simply is unavailable, one way might be to augment the run time system with a mapping of functions to a thread local store of this auxiliary information just like errno. Clojure already comes with batteries to handle this case called push- thread-bindings. Push-thread-bindings allows a function to arbitrarily associate data with predetermined vars, and get-thread- bindings provides a function to retreive the information stored in the thread. Then, all that would be necessary to establish multiple returns would be to establish a dynamic var associated with each function that wanted to be able to return multiple objects. The interested caller would just know to read this preveriously var (probably via macro) to get the extra data it wanted. The only downside is that, per the documentation, push-thread-bindings does not handle its own housekeeping: it requires the calling function to ensure that the thread bindings are cleaned up via pop-thread- bindings, called in a finally block. This, of course, is not ideal, because the function that establishes the extra information can't be sure when or even if its own caller will use it! A more magical push- thread-bindings that could clean up after itself upon thread completion is necessary. Essentially, it sounds like dynamic vars work basically the way you want. If there is a good way to garbage collect them when the thread dies, a couple macros will make implementation relatively straightforward. By the way, more flexibly handling dynamic vars seems to be part of a general goal for the future: http://dev.clojure.org/display/design/Improve+Binding. Directly using the ThreadLocal class might also provide you with all the machinery necessary to implement this idea and provide garbage collection for free on thread completion. 2. Use and Abuse Metadata on the FunctionSimilar to memoize, we could store extra return values in function's own metadata via an atom that mapped Java thread-id's to extra return values. To return an extra value, the function would simply grab its own metadata set an extra return value by thread-id. Callers wanting to access this extra data would be provided a macro to look this value up on demand, probably passing the function (something like (return-more! f)). Subsequent calls could just continually update this value. This essentially would emulate thread-local variables though, so the first approach is probably preferable. Either way, this sounds like it might be implementable via a nice little library without having to change the language at all, with very little namespace mucking required. Hope that helps,Mark On Jan 3, 12:24 pm, nchurch nchubr...@gmail.com wrote: I think, I'll stop here. You won't convince me that this approach is practicable anytime soon. ;-) I certainly won't try too hard either. I'm not questioning here whether it is immediately practicable to implement (maybe not, and in case a very long discussion) but is it potentially useful? (A shorter discussion.) In answer to your questions: The name of a returned value, of course, \does become part of the interface. Perhaps library writers would want to have a discipline of using their own internal names and then passing them out in one final values call inside of a let. As to the second: the recursive (bar ...) call has no effect on any foo-values used outside of it, whether before or after. This accords with our expectation for how functions work. Think of Values as a magical macro that \at \runtime reaches outside of the function it was used in and writes a little let inside the calling function's scope. Is this possible? I don't think so. Presumably it would have to be part of the language, just like Values is part of Common Lisp. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send
Re: accessing multiple return values
It seems like we're talking about conflation of language implementation details to simulate a hash-map. Why not just use a hash-map for named values? Or a lazy sequence? A function returns a 'value', which can be a single thing, a collection of things, or even an arbitrary graph of things. If a indirection by a name is required to reach a value later, then what you really have as your return value conceptually is a map, and actually returning the map would be more obvious than projecting the map onto a namespace, with all the baggage that comes with that. The downside would be having to refer to the first value in calling code by name, which I believe is an upside due to its clarity. A function that returns 'multiple objects' is equivalent to a function that returns a meta-object that points to the multiple objects. Isn't that much more explicit than documenting a hidden var with all its concurrency semantics, simpler, less verbose AFAICT, and more of a functional approach? On Jan 3, 6:05 pm, meb meba...@gmail.com wrote: I see two fairly straightforward paths to simulating multiple returns without breaking existing callers. Both take advantage of thread-local state and establish one convention for the caller: before calling the function again, every caller interested the extra return values must ask for these extra returned values before calling the function again. 1. Use and Abuse VarsThe multiple return idea sounds a lot like the global errno facility used commonly in C to communicate out of band errors that cannot be conveniently conveyed via the function's actually return, except with namespacing to help multiple functions cooperate for the scarce resources. That bit of magic can be pretty nasty and metadata usually solves the majority of cases needed to move that auxiliary information (errno changed from a simple global variable to a complicated macro with the advent of multi-threaded C applications). However, in cases that metadata simply is unavailable, one way might be to augment the run time system with a mapping of functions to a thread local store of this auxiliary information just like errno. Clojure already comes with batteries to handle this case called push- thread-bindings. Push-thread-bindings allows a function to arbitrarily associate data with predetermined vars, and get-thread- bindings provides a function to retreive the information stored in the thread. Then, all that would be necessary to establish multiple returns would be to establish a dynamic var associated with each function that wanted to be able to return multiple objects. The interested caller would just know to read this preveriously var (probably via macro) to get the extra data it wanted. The only downside is that, per the documentation, push-thread-bindings does not handle its own housekeeping: it requires the calling function to ensure that the thread bindings are cleaned up via pop-thread- bindings, called in a finally block. This, of course, is not ideal, because the function that establishes the extra information can't be sure when or even if its own caller will use it! A more magical push- thread-bindings that could clean up after itself upon thread completion is necessary. Essentially, it sounds like dynamic vars work basically the way you want. If there is a good way to garbage collect them when the thread dies, a couple macros will make implementation relatively straightforward. By the way, more flexibly handling dynamic vars seems to be part of a general goal for the future:http://dev.clojure.org/display/design/Improve+Binding. Directly using the ThreadLocal class might also provide you with all the machinery necessary to implement this idea and provide garbage collection for free on thread completion. 2. Use and Abuse Metadata on the FunctionSimilar to memoize, we could store extra return values in function's own metadata via an atom that mapped Java thread-id's to extra return values. To return an extra value, the function would simply grab its own metadata set an extra return value by thread-id. Callers wanting to access this extra data would be provided a macro to look this value up on demand, probably passing the function (something like (return-more! f)). Subsequent calls could just continually update this value. This essentially would emulate thread-local variables though, so the first approach is probably preferable. Either way, this sounds like it might be implementable via a nice little library without having to change the language at all, with very little namespace mucking required. Hope that helps,Mark On Jan 3, 12:24 pm, nchurch nchubr...@gmail.com wrote: I think, I'll stop here. You won't convince me that this approach is practicable anytime soon. ;-) I certainly won't try too hard either. I'm not questioning here whether it is immediately practicable to implement (maybe not, and in case a very
Re: accessing multiple return values
On Tue, Jan 3, 2012 at 6:05 PM, meb meba...@gmail.com wrote: I see two fairly straightforward paths to simulating multiple returns without breaking existing callers. Both take advantage of thread-local state and establish one convention for the caller ... Both of them have reentrancy problems -- in the push-thread-bindings case, only if a caller doesn't use the extra values (and pop the thread bindings), but that may be a common case. You mentioned memoization, though, which might offer a superior alternative in the case of pure functions: (let [foo-memo-cache (atom {}) bar-memo-cache (atom {})] (defn foo ...) (defn bar ...)) ... (foo x y) (bar x y) The idea here is that foo and bar can see and modify one anothers' memoization caches. If computing (foo x y) can cheaply also compute (bar x y), then it can stuff that into bar's memoization cache and return its own result; the subsequent call to (bar x y) then doesn't duplicate the computation, as the result's cached. Works well only if foo and bar are (conceptually) pure functions. May be done so that foo and bar can be called in either order. No problems with reentrancy or thread-safety. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
accessing multiple return values
Someone was asking on the list here about multiple return values, which Clojure does not have. If the facility were ever added, perhaps multiple values could be accessed via namespaces. Functions would possess another level of namespace and have the ability to inject values into the environment under that namespace. For instance: (defn quotient [x y] . (values quotient remainder)) (clojure.core/quotient 5 2) -- 2 clojure.core/quotient/remainder -- 1 This seems simpler than the Common Lisp way. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: accessing multiple return values
nchurch nchubr...@gmail.com writes: Hi, Someone was asking on the list here about multiple return values, which Clojure does not have. If the facility were ever added, perhaps multiple values could be accessed via namespaces. Functions would possess another level of namespace and have the ability to inject values into the environment under that namespace. For instance: (defn quotient [x y] . (values quotient remainder)) (clojure.core/quotient 5 2) -- 2 clojure.core/quotient/remainder -- 1 This seems simpler than the Common Lisp way. I don't think so. And there are several major problems with that approach. First of all, your clojure.core.quotient/remainder var needs to be a mutable, thread-local var, because else you couldn't be sure that 1 is the remainder of the quotient call directly above, or the remainder of a call that happened a blink later in another thread (or ForkJoinTask). Another problem is that if the var name is determined by the name of the local var in the function which is given to `values', then changing its name requires changing all places where clojure.core.quotient/remainder is used. Bye, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: accessing multiple return values
On Mon, Jan 2, 2012 at 2:16 PM, Tassilo Horn tass...@member.fsf.org wrote: nchurch nchubr...@gmail.com writes: Hi, Someone was asking on the list here about multiple return values, which Clojure does not have. If the facility were ever added, perhaps multiple values could be accessed via namespaces. Functions would possess another level of namespace and have the ability to inject values into the environment under that namespace. For instance: (defn quotient [x y] . (values quotient remainder)) (clojure.core/quotient 5 2) -- 2 clojure.core/quotient/remainder -- 1 This seems simpler than the Common Lisp way. I don't think so. And there are several major problems with that approach. First of all, your clojure.core.quotient/remainder var needs to be a mutable, thread-local var, because else you couldn't be sure that 1 is the remainder of the quotient call directly above, or the remainder of a call that happened a blink later in another thread (or ForkJoinTask). Another problem is that if the var name is determined by the name of the local var in the function which is given to `values', then changing its name requires changing all places where clojure.core.quotient/remainder is used. On top of all that, how often is this needed anyway where destructuring or metadata can't solve the problem? When performance isn't a concern and you control the calling functions (or they're generic things like map and reduce that just pass the return value through to code you control, such as whatever processes the map sequence output) you can replace something with a vector of that something and additional values, and destructure. And even when you don't control the calling functions, and replacing the return value with a wrapper of any kind would blow up, if that return value is a seq, vector, or other Clojure data type that supports metadata, you can attach metadata (and, to avoid collisions, use namespaced keywords in it) to smuggle the extra values out. In a similar vein, if a non-primitive, non-final Java type is the expected value, you can subclass it with added fields and getters to smuggle out the extra values (the old decorator pattern) using deftype or reify or proxy. (Some of these don't let you explicitly add fields, but all of them let you define getters that close over locals in the function returning them. You'll need a definterface specifying the getters, too.) When the only objection to destructuring is performance, as is likely with your quotient-and-remainder case or similar mathematical-transform cases, there's a final judo move available: continuation-passing. You make the code that was going to *use* the results into a *parameter*, which takes all of the results as arguments. Pre-1.3 you'd probably write something like (defmacro quot-and-rem [a b q r forms] `(let [a# (long ~a) b# (long ~b) t# (... a# ... b# ...) ~q (...) ~r (...)] ~@forms)) which would execute forms with q and r bound to the quot and rem, respectively, of a and b. Now you can also pass a function expecting two long primitives to a function that takes two long primitives and a function and calls that function with two long primitives, the quotient and the remainder. (The macro approach still gets you the potential benefits and drawbacks of inlining both functions: avoiding the overhead of calls and parameter passing, twice, but also making the current function larger, perhaps large enough to cause cache misses. Obviously it also lets you stay source-compatible with older Clojure versions, for whatever that's worth.) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
On Dec 23, 5:08 am, Alan Malloy a...@malloys.org wrote: It turns out even this is not true, becauseproxyuses some kind of deep JVM magic called (appropriately)ProxyClasses. So every time you write (proxy[Object] (...anything at all...)), you get an instance of the same class, initialized with a different map of function pointers. That is, for any superclass and set of interfaces, exactly oneproxy class exists (possibly one per namespace?), of which all suchproxy objects are instances. This sounds good. Thanks. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
On Dec 14, 5:33 pm, Tom Faulhaber tomfaulha...@gmail.com wrote: Razvan, I believe that proxy actually only creates a new class per call site, not per instance. However, I can't completely swear to this. Anyone with more detailed knowledge than I have want to comment? Assuming I'm right,, you should be fine to have lots of instances. HTH, Tom What do you mean by site? For example, how is it when I'm creating my proxy inside a macro? (and assuming this macro is called many times) (defmacro [a-class] (proxy (a-class) )) Razvan -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
On Dec 22, 8:52 am, Razvan Rotaru razvan.rot...@gmail.com wrote: What do you mean by site? For example, how is it when I'm creating my proxy inside a macro? (and assuming this macro is called many times) (defmacro [a-class] (proxy (a-class) )) Razvan Once all code is macroexpanded, every use of proxy (actually what proxy expands into) will result in a new class. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
On Dec 22, 5:48 pm, Brian Goslinga brian.gosli...@gmail.com wrote: On Dec 22, 8:52 am, Razvan Rotaru razvan.rot...@gmail.com wrote: What do you mean by site? For example, how is it when I'm creating my proxy inside a macro? (and assuming this macro is called many times) (defmacro [a-class] (proxy (a-class) )) Razvan Once all code is macroexpanded, every use of proxy (actually what proxy expands into) will result in a new class. It turns out even this is not true, because proxy uses some kind of deep JVM magic called (appropriately) Proxy Classes. So every time you write (proxy [Object] (...anything at all...)), you get an instance of the same class, initialized with a different map of function pointers. That is, for any superclass and set of interfaces, exactly one proxy class exists (possibly one per namespace?), of which all such proxy objects are instances. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
Thanks. On Dec 14, 8:30 pm, Alan Malloy a...@malloys.org wrote: Correct, just like closures and reifies. On Dec 14, 7:33 am, Tom Faulhaber tomfaulha...@gmail.com wrote: Razvan, I believe that proxy actually only creates a new class per call site, not per instance. However, I can't completely swear to this. Anyone with more detailed knowledge than I have want to comment? Assuming I'm right,, you should be fine to have lots of instances. HTH, Tom On Dec 13, 10:47 am, Razvan Rotaru razvan.rot...@gmail.com wrote: Thanks Tom. Using proxy like this could work. But i'm worried about one thing.What happens if I have many instances? With proxy there's a new class with each instance. Could I run out of permgen space? On Dec 13, 9:38 am, Tom Faulhaber tomfaulha...@gmail.com wrote: Razvan, I think that you can implement your idea of extending the class with proxy in the following way (originally suggested to me by Rich Hickey Chris Houser for use with the pretty printer): (let [extra-fields (ref {:field1 extra-value1, :field2 extra-value2}] (proxy [Writer IDeref] (deref [] extra-fields) (write [x] ...) other funcs)) You don't need to make the extra-values item a ref if you will set the values immutably at create time. You can see the full example of this athttps://github.com/clojure/clojure/blob/1f11ca3ef9cd0585abfbe4a9e7609... The rest of that module is an abomination that was written when I was still under the influence of CLOS O-O. Hope that helps, Tom On Dec 12, 5:10 pm, Stephen Compall stephen.comp...@gmail.com wrote: On Mon, 2011-12-12 at 10:54 -0800, Razvan Rotaru wrote: - function returns a value which is a java instance (not possible to change here, or at least not from what I see - it needs to be a java instance) - i need to be able to call some function which gets some values that are not part of the java class You should approach such a need with great trepidation: [org.jboss.netty/netty 3.2.7.Final] (import 'org.jboss.netty.util.internal.ConcurrentIdentityWeakKeyHashMap) (def ^:private asides (ConcurrentIdentityWeakKeyHashMap.)) (defn function-with-two-return-values [...] (let [retval ...] (.put asides retval extra-data) retval)) (let [x (function-with-two-return-values ...)] (prn x) (prn (.get asides x))) -- Stephen Compall ^aCollection allSatisfy: [:each|aCondition]: less is better -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
Razvan, I believe that proxy actually only creates a new class per call site, not per instance. However, I can't completely swear to this. Anyone with more detailed knowledge than I have want to comment? Assuming I'm right,, you should be fine to have lots of instances. HTH, Tom On Dec 13, 10:47 am, Razvan Rotaru razvan.rot...@gmail.com wrote: Thanks Tom. Using proxy like this could work. But i'm worried about one thing.What happens if I have many instances? With proxy there's a new class with each instance. Could I run out of permgen space? On Dec 13, 9:38 am, Tom Faulhaber tomfaulha...@gmail.com wrote: Razvan, I think that you can implement your idea of extending the class with proxy in the following way (originally suggested to me by Rich Hickey Chris Houser for use with the pretty printer): (let [extra-fields (ref {:field1 extra-value1, :field2 extra-value2}] (proxy [Writer IDeref] (deref [] extra-fields) (write [x] ...) other funcs)) You don't need to make the extra-values item a ref if you will set the values immutably at create time. You can see the full example of this athttps://github.com/clojure/clojure/blob/1f11ca3ef9cd0585abfbe4a9e7609... The rest of that module is an abomination that was written when I was still under the influence of CLOS O-O. Hope that helps, Tom On Dec 12, 5:10 pm, Stephen Compall stephen.comp...@gmail.com wrote: On Mon, 2011-12-12 at 10:54 -0800, Razvan Rotaru wrote: - function returns a value which is a java instance (not possible to change here, or at least not from what I see - it needs to be a java instance) - i need to be able to call some function which gets some values that are not part of the java class You should approach such a need with great trepidation: [org.jboss.netty/netty 3.2.7.Final] (import 'org.jboss.netty.util.internal.ConcurrentIdentityWeakKeyHashMap) (def ^:private asides (ConcurrentIdentityWeakKeyHashMap.)) (defn function-with-two-return-values [...] (let [retval ...] (.put asides retval extra-data) retval)) (let [x (function-with-two-return-values ...)] (prn x) (prn (.get asides x))) -- Stephen Compall ^aCollection allSatisfy: [:each|aCondition]: less is better -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
Correct, just like closures and reifies. On Dec 14, 7:33 am, Tom Faulhaber tomfaulha...@gmail.com wrote: Razvan, I believe that proxy actually only creates a new class per call site, not per instance. However, I can't completely swear to this. Anyone with more detailed knowledge than I have want to comment? Assuming I'm right,, you should be fine to have lots of instances. HTH, Tom On Dec 13, 10:47 am, Razvan Rotaru razvan.rot...@gmail.com wrote: Thanks Tom. Using proxy like this could work. But i'm worried about one thing.What happens if I have many instances? With proxy there's a new class with each instance. Could I run out of permgen space? On Dec 13, 9:38 am, Tom Faulhaber tomfaulha...@gmail.com wrote: Razvan, I think that you can implement your idea of extending the class with proxy in the following way (originally suggested to me by Rich Hickey Chris Houser for use with the pretty printer): (let [extra-fields (ref {:field1 extra-value1, :field2 extra-value2}] (proxy [Writer IDeref] (deref [] extra-fields) (write [x] ...) other funcs)) You don't need to make the extra-values item a ref if you will set the values immutably at create time. You can see the full example of this athttps://github.com/clojure/clojure/blob/1f11ca3ef9cd0585abfbe4a9e7609... The rest of that module is an abomination that was written when I was still under the influence of CLOS O-O. Hope that helps, Tom On Dec 12, 5:10 pm, Stephen Compall stephen.comp...@gmail.com wrote: On Mon, 2011-12-12 at 10:54 -0800, Razvan Rotaru wrote: - function returns a value which is a java instance (not possible to change here, or at least not from what I see - it needs to be a java instance) - i need to be able to call some function which gets some values that are not part of the java class You should approach such a need with great trepidation: [org.jboss.netty/netty 3.2.7.Final] (import 'org.jboss.netty.util.internal.ConcurrentIdentityWeakKeyHashMap) (def ^:private asides (ConcurrentIdentityWeakKeyHashMap.)) (defn function-with-two-return-values [...] (let [retval ...] (.put asides retval extra-data) retval)) (let [x (function-with-two-return-values ...)] (prn x) (prn (.get asides x))) -- Stephen Compall ^aCollection allSatisfy: [:each|aCondition]: less is better -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
Thanks Tom. Using proxy like this could work. But i'm worried about one thing.What happens if I have many instances? With proxy there's a new class with each instance. Could I run out of permgen space? On Dec 13, 9:38 am, Tom Faulhaber tomfaulha...@gmail.com wrote: Razvan, I think that you can implement your idea of extending the class with proxy in the following way (originally suggested to me by Rich Hickey Chris Houser for use with the pretty printer): (let [extra-fields (ref {:field1 extra-value1, :field2 extra-value2}] (proxy [Writer IDeref] (deref [] extra-fields) (write [x] ...) other funcs)) You don't need to make the extra-values item a ref if you will set the values immutably at create time. You can see the full example of this athttps://github.com/clojure/clojure/blob/1f11ca3ef9cd0585abfbe4a9e7609... The rest of that module is an abomination that was written when I was still under the influence of CLOS O-O. Hope that helps, Tom On Dec 12, 5:10 pm, Stephen Compall stephen.comp...@gmail.com wrote: On Mon, 2011-12-12 at 10:54 -0800, Razvan Rotaru wrote: - function returns a value which is a java instance (not possible to change here, or at least not from what I see - it needs to be a java instance) - i need to be able to call some function which gets some values that are not part of the java class You should approach such a need with great trepidation: [org.jboss.netty/netty 3.2.7.Final] (import 'org.jboss.netty.util.internal.ConcurrentIdentityWeakKeyHashMap) (def ^:private asides (ConcurrentIdentityWeakKeyHashMap.)) (defn function-with-two-return-values [...] (let [retval ...] (.put asides retval extra-data) retval)) (let [x (function-with-two-return-values ...)] (prn x) (prn (.get asides x))) -- Stephen Compall ^aCollection allSatisfy: [:each|aCondition]: less is better -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
I don't want to change the interface i'm exposing to the outer world. May be that I'm thinking too javaish, but what I miss here is a possibility to extend the base class. :) On Dec 12, 9:31 pm, James Reeves jree...@weavejester.com wrote: On 12 December 2011 18:54, Razvan Rotaru razvan.rot...@gmail.com wrote: - function returns a value which is a java instance (not possible to change here, or at least not from what I see - it needs to be a java instance) Why does it need to be a Java instance? - James -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
Thanks. I don't know how this hashmap works, but at the first glance there seems to be one problem: the two values don't get garbage collected at the same time. I'll look more into it, thanks. On Dec 13, 3:10 am, Stephen Compall stephen.comp...@gmail.com wrote: On Mon, 2011-12-12 at 10:54 -0800, Razvan Rotaru wrote: - function returns a value which is a java instance (not possible to change here, or at least not from what I see - it needs to be a java instance) - i need to be able to call some function which gets some values that are not part of the java class You should approach such a need with great trepidation: [org.jboss.netty/netty 3.2.7.Final] (import 'org.jboss.netty.util.internal.ConcurrentIdentityWeakKeyHashMap) (def ^:private asides (ConcurrentIdentityWeakKeyHashMap.)) (defn function-with-two-return-values [...] (let [retval ...] (.put asides retval extra-data) retval)) (let [x (function-with-two-return-values ...)] (prn x) (prn (.get asides x))) -- Stephen Compall ^aCollection allSatisfy: [:each|aCondition]: less is better -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
On Tue, 2011-12-13 at 10:52 -0800, Razvan Rotaru wrote: Thanks. I don't know how this hashmap works, but at the first glance there seems to be one problem: the two values don't get garbage collected at the same time. There are problems with weak hashmaps, but I wouldn't count that among them. -- Stephen Compall ^aCollection allSatisfy: [:each|aCondition]: less is better -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
multiple return values
Hi, I read that there's no such thing as lisp-like multiple values return in clojure. We can use vectors, and the destructuring feature helps also. However, for what I'm trying to do I need to emulate somehow the following behavior: - function returns a value which is a java instance (not possible to change here, or at least not from what I see - it needs to be a java instance) - i need to be able to call some function which gets some values that are not part of the java class My first intuition was extend the base class (thinking as a Java programmer). But this is not possible. Not with proxy (which does not allow new fields) and not with reify (which does not extend classes). So I'm thinking of using defrecords with protocols, where one slot would be my java instance, and the rest would be my additional fields. However I have a problem. Whenever my record value is used, I need to use the java instance (sort of as a default field). For example: (defrecord myrecord [java-field myfield1 myfield2]) (def q (myrecord. java-intance foo bar)) And then evaluation of q should be equivalent of (:java-field q). This is nonsense, I know but I need some way to get around this. Any idea would be greatly appreciated. (What I need is basically a workaround for the lisp-style multiple values: in the default context, my value is evaluated to the java instance, and with some special context I can get the values of other fields as well.). Thanks, Razvan -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
On 12 December 2011 18:54, Razvan Rotaru razvan.rot...@gmail.com wrote: - function returns a value which is a java instance (not possible to change here, or at least not from what I see - it needs to be a java instance) Why does it need to be a Java instance? - James -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
On Mon, Dec 12, 2011 at 10:54 AM, Razvan Rotaru razvan.rot...@gmail.com wrote: Hi, I read that there's no such thing as lisp-like multiple values return in clojure. We can use vectors, and the destructuring feature helps also. However, for what I'm trying to do I need to emulate somehow the following behavior: - function returns a value which is a java instance (not possible to change here, or at least not from what I see - it needs to be a java instance) - i need to be able to call some function which gets some values that are not part of the java class My first intuition was extend the base class (thinking as a Java programmer). But this is not possible. Not with proxy (which does not allow new fields) and not with reify (which does not extend classes). So I'm thinking of using defrecords with protocols, where one slot would be my java instance, and the rest would be my additional fields. However I have a problem. Whenever my record value is used, I need to use the java instance (sort of as a default field). For example: (defrecord myrecord [java-field myfield1 myfield2]) (def q (myrecord. java-intance foo bar)) And then evaluation of q should be equivalent of (:java-field q). This is nonsense, I know but I need some way to get around this. Any idea would be greatly appreciated. (What I need is basically a workaround for the lisp-style multiple values: in the default context, my value is evaluated to the java instance, and with some special context I can get the values of other fields as well.). Thanks, Razvan (declare ^:dynamic *r2*) (defn function-with-two-return-values [x] (set! *r2* (dec x)) (inc x)) (binding [*r2* nil] (prn (function-with-two-return-values 1)) (prn *r2*)) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
Intuitively it sounds like you are making something much more complicated than it needs to be. I'd say to return from your computation a vector with the two values, or possibly a map with them. If you need to create some kind of Java interop object, then map the result of the computation to that object type if need be. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
On Mon, 2011-12-12 at 10:54 -0800, Razvan Rotaru wrote: - function returns a value which is a java instance (not possible to change here, or at least not from what I see - it needs to be a java instance) - i need to be able to call some function which gets some values that are not part of the java class You should approach such a need with great trepidation: [org.jboss.netty/netty 3.2.7.Final] (import 'org.jboss.netty.util.internal.ConcurrentIdentityWeakKeyHashMap) (def ^:private asides (ConcurrentIdentityWeakKeyHashMap.)) (defn function-with-two-return-values [...] (let [retval ...] (.put asides retval extra-data) retval)) (let [x (function-with-two-return-values ...)] (prn x) (prn (.get asides x))) -- Stephen Compall ^aCollection allSatisfy: [:each|aCondition]: less is better -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: multiple return values
Razvan, I think that you can implement your idea of extending the class with proxy in the following way (originally suggested to me by Rich Hickey Chris Houser for use with the pretty printer): (let [extra-fields (ref {:field1 extra-value1, :field2 extra-value2}] (proxy [Writer IDeref] (deref [] extra-fields) (write [x] ...) other funcs)) You don't need to make the extra-values item a ref if you will set the values immutably at create time. You can see the full example of this at https://github.com/clojure/clojure/blob/1f11ca3ef9cd0585abfbe4a9e7609be8b255123f/src/clj/clojure/pprint/pretty_writer.clj#L371 The rest of that module is an abomination that was written when I was still under the influence of CLOS O-O. Hope that helps, Tom On Dec 12, 5:10 pm, Stephen Compall stephen.comp...@gmail.com wrote: On Mon, 2011-12-12 at 10:54 -0800, Razvan Rotaru wrote: - function returns a value which is a java instance (not possible to change here, or at least not from what I see - it needs to be a java instance) - i need to be able to call some function which gets some values that are not part of the java class You should approach such a need with great trepidation: [org.jboss.netty/netty 3.2.7.Final] (import 'org.jboss.netty.util.internal.ConcurrentIdentityWeakKeyHashMap) (def ^:private asides (ConcurrentIdentityWeakKeyHashMap.)) (defn function-with-two-return-values [...] (let [retval ...] (.put asides retval extra-data) retval)) (let [x (function-with-two-return-values ...)] (prn x) (prn (.get asides x))) -- Stephen Compall ^aCollection allSatisfy: [:each|aCondition]: less is better -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Multiple return values
On Tue, Oct 21, 2008 at 7:48 AM, Jeffrey Chu [EMAIL PROTECTED] wrote: Hi, If you really need multiple value calls, you can always try to emulate parts of it with some fancy macros. I've hacked up a quick proof of concept - I haven't gotten a chance to test it too much, but it seems to work. http://paste.lisp.org/display/68919 Nice. I tried to hack a simple macro for this on my way to work this morning. It worked reasonably, but choked on nested statements (and probably a lot of other things as well). Yours looks a lot better. :) Cheers, -- Fredrik == What am I up to? http://twitter.com/appelberg --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Multiple return values
Hi all, The CL feature for handling multiple return values from a function come in really handy sometimes and make for cleaner APIs. For example, the ROUND function returns the integer part of a float as the regular value (as this is what you want most of the time), but optionally also returns the floating point part in case you want it. I haven't found anything like MULTIPLE-VALUE-BIND in Clojure. Are there any plans of incorporating any kind of mechanism for multiple return values? Cheers, -- Fredrik == What am I up to? http://twitter.com/appelberg --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Multiple return values
On Oct 20, 3:51 pm, Fredrik Appelberg [EMAIL PROTECTED] wrote: Hi all, The CL feature for handling multiple return values from a function come in really handy sometimes and make for cleaner APIs. For example, the ROUND function returns the integer part of a float as the regular value (as this is what you want most of the time), but optionally also returns the floating point part in case you want it. I haven't found anything like MULTIPLE-VALUE-BIND in Clojure. Are there any plans of incorporating any kind of mechanism for multiple return values? Hi Fredrik, Similar results can be accomplished using vectors and destructuring in Clojure. user= (defn foo [] [:one :two :three]) #=(var user/foo) user= (let [[a b c] (foo)] (println b)) :two nil user= The destructuring capabilities of let are quite nice. A bunch of examples are available in the let reference: http://clojure.org/special_forms Parth Cheers, -- Fredrik == What am I up to?http://twitter.com/appelberg --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Multiple return values
On Oct 20, 7:03 am, Parth Malwankar [EMAIL PROTECTED] wrote: On Oct 20, 3:51 pm, Fredrik Appelberg [EMAIL PROTECTED] wrote: Hi all, The CL feature for handling multiple return values from a function come in really handy sometimes and make for cleaner APIs. For example, the ROUND function returns the integer part of a float as the regular value (as this is what you want most of the time), but optionally also returns the floating point part in case you want it. I haven't found anything like MULTIPLE-VALUE-BIND in Clojure. Are there any plans of incorporating any kind of mechanism for multiple return values? Hi Fredrik, Similar results can be accomplished using vectors and destructuring in Clojure. user= (defn foo [] [:one :two :three]) #=(var user/foo) user= (let [[a b c] (foo)] (println b)) :two nil user= The destructuring capabilities of let are quite nice. A bunch of examples are available in the let reference:http://clojure.org/special_forms We could further combine this by making a scalar equivalent to a vector of length 1; that way, users who expect a function to return one value would not be confused when a vector is returned instead. There's a problem, of course -- how to distinguish between vector-as- holder-of-return-values and vector-as-the-returned-value ? Cheers, -- Michel Salim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Multiple return values
On Mon, Oct 20, 2008 at 1:03 PM, Parth Malwankar [EMAIL PROTECTED]wrote: On Oct 20, 3:51 pm, Fredrik Appelberg [EMAIL PROTECTED] wrote: Hi all, The CL feature for handling multiple return values from a function come in really handy sometimes and make for cleaner APIs. For example, the ROUND function returns the integer part of a float as the regular value (as this is what you want most of the time), but optionally also returns the floating point part in case you want it. I haven't found anything like MULTIPLE-VALUE-BIND in Clojure. Are there any plans of incorporating any kind of mechanism for multiple return values? Hi Fredrik, Similar results can be accomplished using vectors and destructuring in Clojure. user= (defn foo [] [:one :two :three]) #=(var user/foo) user= (let [[a b c] (foo)] (println b)) :two nil user= The destructuring capabilities of let are quite nice. A bunch of examples are available in the let reference: http://clojure.org/special_forms I agree that Clojure's let form goes a long way towards making multiple return values easy to handle. What's missing, though, is the ability to return a single value or multiple values depending on the context in which the function was called. I.e, if the call happens enclosed in MULTIPLE-VALUE-BIND, I get all the returned values, otherwise I get a single one. Anyway, this is a really nifty feature in CL, but it might not be necessary in Clojure as its 'let' form is more potent. Cheers, -- Fredrik == What am I up to? http://twitter.com/appelberg --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Multiple return values
Hi, If you really need multiple value calls, you can always try to emulate parts of it with some fancy macros. I've hacked up a quick proof of concept - I haven't gotten a chance to test it too much, but it seems to work. http://paste.lisp.org/display/68919 - Jeff On Oct 20, 1:00 pm, Fredrik Appelberg [EMAIL PROTECTED] wrote: On Mon, Oct 20, 2008 at 1:03 PM, Parth Malwankar [EMAIL PROTECTED]wrote: On Oct 20, 3:51 pm, Fredrik Appelberg [EMAIL PROTECTED] wrote: Hi all, The CL feature for handling multiple return values from a function come in really handy sometimes and make for cleaner APIs. For example, the ROUND function returns the integer part of a float as the regular value (as this is what you want most of the time), but optionally also returns the floating point part in case you want it. I haven't found anything like MULTIPLE-VALUE-BIND in Clojure. Are there any plans of incorporating any kind of mechanism for multiple return values? Hi Fredrik, Similar results can be accomplished using vectors and destructuring in Clojure. user= (defn foo [] [:one :two :three]) #=(var user/foo) user= (let [[a b c] (foo)] (println b)) :two nil user= The destructuring capabilities of let are quite nice. A bunch of examples are available in the let reference: http://clojure.org/special_forms I agree that Clojure's let form goes a long way towards making multiple return values easy to handle. What's missing, though, is the ability to return a single value or multiple values depending on the context in which the function was called. I.e, if the call happens enclosed in MULTIPLE-VALUE-BIND, I get all the returned values, otherwise I get a single one. Anyway, this is a really nifty feature in CL, but it might not be necessary in Clojure as its 'let' form is more potent. Cheers, -- Fredrik == What am I up to?http://twitter.com/appelberg --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---