I'm trying to make an array-like data structure in Scheme, and since I need to refer to it (and alter it!) often, I want to give it a name. But from what I've read on various tutorial sites, it looks like the only way to name the list for later reference is with define. That would be fine, except it also looks like once I initialize a list with define, it becomes more complicated altering or adding to said list. For example, it seems like I wouldn't be able to do just (append wordlist (element)), I'd need some manner of ! bang.
Basically my questions boil down to: Is define my only hope of naming a list? And if so, am I stuck jumping through hoops changing its elements? Thanks.
Yes, define is the way for naming things in Scheme. A normal list in Scheme won't allow you to change its elements, because it's immutable - that's one of the things you'll have to learn to live with when working with a functional data structure. Of course you can add elements to it or remove elements to it, but those operations will produce new lists, you can't change the elements in-place.
The other option is to use mutable lists instead of normal lists, but if you're just learning to use Scheme, it's better to stick to the immutable lists first and learn the Scheme way to do things in terms of immutable data.
Yes, define is the way to do "assignment" (really naming) in Scheme. Though, if you're writing some kind of package, you might consider wrapping the whole thing inside of a function and then using let to define something you refer to.
Then, of course, you have to have some sort of abstraction to unwrap the functions inside of your "package."
See SICP 2.5 Building Systems with Generic Operations
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-18.html#%_sec_2.5
(append wordlist (element)) is creating a new list. What you might want is to use set! to redirect a reference to the new list, or define a reference to the new list using the same symbol's name.
Related
I've long since known that define is scary and should be used with caution unless you know for sure how your implementation handles it. Out of interest, I recently opened up R7RS and read all that I could find about define and nothing gave me the impression that any of it is implementation dependent. Have I missed something or is define no longer implementation-dependent in R7RS?
You seem to be reading something into the answer you linked which isn’t there.
define has always been well defined, just as well-defined as let is. Most people choose to use define only at the top level of modules to create top-level bindings, but that’s a stylistic choice — it’s also capable of creating local bindings, like let is, if you use it inside and at the top of an ‘internal’ body, such as inside a procedure or a let or similar. Multiple defines in such a context are technically equivalent to letrec*, as another answer noted.
The most common interpretation of define is to replace it with letrec*.
But this problem has indeed many possible interpretations and the language does not impose any. Any interpretation is valid from the viewpoint of the language.
In ruby, Array#delete(obj) will search and remove the specified object from the array. However, may be I'm missing something here but I found the returning value --- the obj itself --- is quite strange and a even a little bit useless.
My humble opinion is that in consistent with methods like sort/sort! and map/map! there should be two methods, e.g. delete/delete!, where
ary.delete(obj) -> new array, with obj removed
ary.delete!(obj) -> ary (after removing obj from ary)
For several reasons, first being that current delete is non-pure, and it should warn the programmer about that just like many other methods in Array (in fact the entire delete_??? family has this issue, they are quite dangerous methods!), second being that returning the obj is much less chainable than returning the new array, for example, if delete were like the above one I described, then I can do multiple deletions in one statement, or I can do something else after deletion:
ary = [1,2,2,2,3,3,3,4]
ary.delete(2).delete(3) #=> [1,4], equivalent to "ary - [2,3]"
ary.delete(2).map{|x|x**2"} #=> [1,9,9,9,16]
which is elegant and easy to read.
So I guess my question is: is this a deliberate design out of some reason, or is it just a heritage of the language?
If you already know that delete is always dangerous, there is no need to add a bang ! to further notice that it is dangerous. That is why it does not have it. Other methods like map may or may not be dangerous; that is why they have versions with and without the bang.
As for why it returns the extracted element, it provides access to information that is cumbersome to refer to if it were not designed like that. The original array after modification can easily be referred to by accessing the receiver, but the extracted element is not easily accessible.
Perhaps, you might be comparing this to methods that add elements, like push or unshift. These methods add elements irrespective of what elements the receiver array has, so returning the added element would be always the same as the argument passed, and you know it, so it is not helpful to return the added elements. Therefore, the modified array is returned, which is more helpful. For delete, whether the element is extracted depends on whether the receiver array has it, and you don't know that, so it is useful to have it as a return value.
For anyone who might be asking the same question, I think I understand it a little bit more now so I might as well share my approach to this question.
So the short answer is that ruby is not a language originally designed for functional programming, neither does it put purity of methods to its priority.
On the other hand, for my particular applications described in my question, we do have alternatives. The - method can be used as a pure alternative of delete in most situations, for example, the code in my question can be implemented like this:
ary = [1,2,2,2,3,3,3,4]
ary.-([2]).-([3]) #=> [1,4], or simply ary.-([2,3])
ary.-([2]).map{|x|x**2"} #=> [1,9,9,9,16]
and you can happily get all the benefits from the purity of -. For delete_if, I guess in most situations select (with return value negated) could be a not-so-great pure candidate.
As for why delete family was designed like this, I think it's more of a difference in point of view. They are supposed to be more of shorthands for commonly needed non-pure procedures than to be juxtaposed with functional-flavored select, map, etc.
I’ve wondered some of these same things myself. What I’ve largely concluded is that the method simply has a misleading name that carries with it false expectations. Those false expectations are what trigger our curiosity as to why the method works like it does. Bottom line—I think it’s a super useful method that we wouldn’t be questioning if it had a name like “swipe_at” or “steal_at”.
Anyway, another alternative we have is values_at(*args) which is functionally the opposite of delete_at in that you specify what you want to keep and then you get the modified array (as opposed to specifying what you want to remove and then getting the removed item).
Is there something like struct-map for records? If not, should I use a struct (the docs discourage use of structs)?
Maybe I am doing the wrong thing completely? I have a rather complex function which currently takes a map of options. I am trying to clarify what option values are acceptable/used (by replacing it with a record). And now I want to interface that to code that has this information in maps (and which contain a superset of the data in the record).
It's not recommended to use records simply for "documentation" - plain old maps are more flexible, simpler, and easier. For documentation, you can merely add a docstring, or a comment, or create a function like (defn make-whatever [thing1 thing2]).
If you still want a record, you have a couple choices depending on whether you're using clojure version 1.3 or higher. If so, (defrecord Whatever ...) also defines a map->Whatever function, and a ->Whatever function that takes positional args. If not, you can write (into (Whatever. nil nil nil) some-map) (passing the right number of nils for the record type).
Can anyone help me out understanding the various parameter passing modes in Scheme? I know Scheme implements parameter passing by value. But how about other modes?
Is there any good documentation for parameter passing in Scheme?
Scheme has only call-by-value function calls. There are other alternatives that can be implemented within the language, but if you're a beginner then it's best to not even try them at this point. If you're looking for a way to pass values "by reference" -- then one option that can sort of make it is to use macros, but you really shouldn't go there. Instead, some Scheme implementations like PLT Scheme provide a "box value": this is a kind of a container that is used like this:
You create a box holding <something> with (box <something>)
You get the value that is stored in a box with (unbox <some-box>)
You change the value that is stored in a box with (set-box! <some-box> <new-value>)
Given these two, you can use such box objects "by value", but their contents is actually a reference. This is very much like C, where all values (most, actually) are passed by-value, yet some of these values can be pointers that you can mutate. BTW, it's best to avoid even these: in Scheme, functional programming is the more common choice and it is therefore better to start with that.
(Once you are more fluent with Scheme, and if you're using a Scheme with sufficient abstractions, then you can learn how to mimic lots of alternatives too.)
To add a bit more...
The four fundamental parameter-passing conventions are call-by-value, call-by-reference, call-by-name, and call-by-need. Scheme, as a "mostly functional" language, relies on call-by-value; variables, once created, generally aren't changed. The other three conventions are pretty similar and you can still do them in Scheme by passing around your values in boxes (using box and unbox), and the boxes act as pointers to values.
Generally, if you find that you need to use call-by-reference in a function, you should probably rethink how you're implementing the function and make it purely functional. Modifying a variable after it's been created using set! is a "side-effect" and is typically avoided in functional programming.
it seems a trivial point, until you realize that you need consistency. Not being a native English speaker, I prefer to ask both for grammar and for style. Which one must be preferred among these method names, returning a list of URIs, each one associated to an object?
objectUriList()
objectsUriList()
objectUrisList()
objectsUrisList()
Also, do you consider good style to make explicit that the returned object is a list in the method name. Maybe something like objectUris() (or its correct form) would be fine and intuitive in any case.
I am not a native English speaker either. Correct form is either objectUriList or objectUris. Regardless of the number of objects and uris.
Car park = park of cars.
PC storage = storage of PCs.
oak forest
etc.
I would call is objectUriList(), it's just easier to say and essentially correct. It's clear that it returns a List which is a set of Uris, so you don't really need the plural there.
However, your final suggestion of objectUris() is also good, depending on how easy it is to see that it returns a List in your IDE.
objectUriList should be the correct answer.
(Unless the function runs on more than one object and then objectsUriList would be preferable).
I like to specify the returned object in the function name but because this is how I worked for my entire life (ever since crappier programming languages). Nowadays, I believe it's not necessary.
I would definitely go with the objectUris() alternative, omitting the "List" suffix. As you say, tidy and intuitive.
It's better to use ObjectUriList.
It is recommended in some circles not to include type names in member/parameter names, so you should drop the List part, but I find that "ObjectUriList" is much more explicit and meaningful than "ObjectUris", especially when you are likely to also have "ObjectUri" as a name nearby.
I think to differentiate between Array and List, It's good to append Array with 's' and List with 'list'.
I usually try to go with singular namespaces but sometimes and contextually plural namespaces as well. For e.g. if your return is always plural such as some keywords, I go with plural but if it can be singular often times, I stick to singular naming convention.