On Sun, 30 Aug 2020 18:26:10 -0400
Anne B <
anne...@gmail.com> wrote:
>On Aug 29, 2020, at 6:48 PM, Elliot Temple <
cu...@curi.us> wrote:
>
>> On Aug 29, 2020, at 1:44 PM, Anne B <
anne...@gmail.com> wrote:
>>
>>> On Aug 28, 2020, at 2:46 PM, Elliot Temple <
cu...@curi.us> wrote:
>>>
>>>> On Aug 28, 2020, at 11:35 AM, Anne B <
anne...@gmail.com> wrote:
>>>>
>>>>> I posted an answer to SICP Exercise 2.3:
>>>>>
>>>>>
https://aelanwave.wordpress.com/2020/08/28/sicp-exercise-2-3/
>
>
>>> This part confused me a little:
>>>
>>>> Any complex data structure can be represented in a variety of ways with the primitive data structures provided by
>>>> a programming language.
>>>
>>> But pairs aren't primitive data structures in Scheme:
>>>
>>>> To enable us to implement the concrete level of our data abstraction, our language provides a compound structure
>>>> called a pair, which can be constructed with the primitive procedure cons.
>>
>> Pairs are primitives in Scheme. I don’t think you know what “primitive” means.
>
>I don’t really know what “primitive” means in a programming context. I looked into it some more.
>
>SICP intro to Chapter 2:
>
>
https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-13.html
>
>> We concentrated in chapter 1 on computational processes and on the role of procedures in program design. We saw how
>> to use primitive data (numbers) and primitive operations (arithmetic operations), how to combine procedures to form
>> compound procedures through composition, conditionals, and the use of parameters, and how to abstract procedures by
>> using define.
>
>They mean that numbers are primitive data. But they don’t necessarily mean that all primitive data are numbers.
Numbers are often primitives.
They don't *have* to be, though - I implemented positive integers (and plus / minus) using lists:
https://repl.it/repls/DearEducatedPort
The way I think of primitives is that they're the magic stuff the interpreter (or compile) gives you. There's no
definition file in scheme for integers - they're sort of implicitly defined by the interpreter. Likewise there's
(apparently) no definition for what a pair/list is written in scheme.
The main reason for this is speed. Adding numbers the normal way is much faster than my example because there are
dedicated CPU instructions for adding numbers and the interpreter knows how to use them. My way needs to go through
lots of scheme functions and do a lot more work to add two numbers.
>> From the perspective of the procedure linear-combination, it is irrelevant what a, b, x, and y are and even more
>> irrelevant how they might happen to be represented in terms of more primitive data.
>
>“more primitive data” means that there are degrees of primitiveness of data.
Sort of - the book isn't wrong but you can also look at primitiveness as yes/no. Primitives are usually numbers,
strings, lists, true/false, that sort of thing. Either data is a primitive or it's made of other data. If it's made of
other data, that data *might* be primitive, or it could be other combinations of data. (there's no limit on this, btw)
Example: a key-value store (also called a map). let's say we have some functions:
; just an empty map
(empty)
; take a map `m` and set the key `k` to point to the value `v`
; it should overwrite older values for the same key
(set k v m)
; take a map `m` and get the value pointed to by `k`
(get k m)
what might `m` look like as data? One way would be a list of pairs, where each pair stores a k,v pair. If we did that:
- `(empty)` would just return an empty list.
- `(set k v m)` would look for some existing key=k,
- if it found one it'd return a list that was *nearly* the same as m, except the old pair with key `k` would now have
the new value `v`.
- if it didn't find one it'd return the original list with the pair `(k v)` appended to it
- `(get k m)` would search the list for some key=k and return the associated value if it found the right key or do
something else if it didn't (either crash, or return null or something)
Can you see how our map is made of other data structures (lists and pairs) so it's not primitive?
Note: I'm not sure if lists are primitives in scheme; I get the feeling they're just nested pairs, and pairs are
primitives.
>> One key idea in dealing with compound data is the notion of closure -- that the glue we use for combining data
>> objects should allow us to combine not only primitive data objects, but compound data objects as well.
>
>I think this implies that primitive data objects and compound data objects are mutually exclusive categories.
Yup.
Yes, it's still the same.
One way you can think about "more primitive data": how many layers of abstraction is the data structure building on?
If you have a number - that's a primitive (unless you're doing silly things like my example above)
If you have a *map of strings to numbers* - that's not a primitive
If you have a *map of strings to (a map of numbers to numbers)* - that's not a primitive
one place you might have a map of strings to (a map of numbers to numbers) is like phone prefixes. you could do like:
(get 10036 (get "NY" m)) ; returns 202 maybe
in some sense our map of strings to a map of numbers to numbers is "less primitive" than just a map of strings to
numbers, but they're also both *not primitives*. However, the map of maps has more abstraction between it and primitive
values.
>> To enable us to implement the concrete level of our data abstraction, our language provides a compound structure
>> called a pair, which can be constructed with the primitive procedure cons.
>
>A pair is a “compound structure”. Is that the same as a “compound data object” from the quote above? Maybe not?
>Because it it’s the same, and I read correctly that “primitive data objects” are different from “compound data
>objects”, then pairs wouldn’t be “primitive data objects”. So then when Elliot says “Pairs are primitives in Scheme”,
>he must mean something different by “primitives” than “primitive data objects”. This is confusing.
> A pair is a “compound structure”. Is that the same as a “compound data object” from the quote above?
No, I think they mean it's just made of other stuff. It can still be a primitive because it's defined by the
interpreter and not implemented in scheme.
>I’m going to search outside of SICP for “primitive”.
>
>
https://www.webopedia.com/TERM/P/primitive.html
>
>> In programming, primitives are the basic operations supported by the programming language.
>
>This seems clear. But it’s talking about operations, not data or data structures. So in Scheme, primitives are the
>procedures that come already defined. That’s how I’d been thinking of primitive procedures.
Primitives can be data and procedures/functions (b/c they can be anything not written in the language itself, provided
by the runtime).
The line between them is actually blurry. like you can think of the number `0` as a shortcut for "the result of a
function which returns zero". that might sound circular but languages don't *start* with numbers defined, the symbols
in source code need to be interpreted into something computers understand. that's where the interpreter comes in.
>An analogous meaning for primitive data structures would be data structures that come already in Scheme. In that
>sense, pairs are primitive because Scheme recognizes them without telling it anything additional.
Yeah, that's a decent way to think about it.
>
https://whatis.techtarget.com/definition/primitive
>
>> 1) In computer programming, a primitive (pronounced PRIH-muh-teev ) is a basic interface or segment of code that can
>> be used to build more sophisticated program elements or interfaces.
>
>This is a different meaning than the one just above it, right?
Different level of abstraction, but roughly the same idea.
>
https://en.wikipedia.org/wiki/Primitive_data_type
>
>> In computer science, primitive data type is either of the following:[citation needed]
>>
>> • a basic type is a data type provided by a programming language as a basic building block. Most languages
>> allow more complicated composite types to be recursively constructed starting from basic types.
>>
>> • a built-in type is a data type for which the programming language provides built-in support.
>>
>> In most programming languages, all basic data types are built-in. In addition, many languages also provide a set of
>> composite data types.
>
>By this definition, pairs could be a primitive data type in Scheme, since they are built in. My guess is that
>“composite” here means the same thing as “compound” in the SICP quotes, which is “built up from something more basic”.
Yes, but annoyingly it is simplistic - languages can provide complex types as primitives.
Example: usually you can think of "lists" and "arrays" to be the same thing in programming languages.
However, Purescript has `Array` as a primitive, but not `List`
* Documentation for Array:
https://pursuit.purescript.org/builtins/docs/Prim#t:Array
* Documentation for List:
https://pursuit.purescript.org/packages/purescript-lists/5.4.1/docs/Data.List.Types#t:List
* Definition for List:
https://github.com/purescript/purescript-lists/blob/62900a56f6864638c952575dfd211a1cc55be7da/src/Data/List/Types.purs#L36
>
https://en.wikipedia.org/wiki/Scheme_(programming_language)
>
>> Disjointness of primitive datatypes[edit]
>> In Scheme the primitive datatypes are disjoint. Only one of the following predicates can be true of any Scheme
>> object: boolean?, pair?, symbol?, number?, char?, string?, vector?, port?, procedure?.
>
>This confirms that pairs are “primitive datatypes” in Scheme. Are “primitive data structure”, “primitive data object”,
>and “primitive datatype” all the same thing? I don’t know.
I given the bits you've copied I'd say it's safe to consider them the same thing. I'd say there are some subtle
differences between the terms, but you probably don't need to worry about it unless there's an issue that comes up.
Actually a grammar example might work well:
* datatypes are *types* of things, like "verb", "preposition", etc.
* a data structure is made of stuff, like *prepositional phrase*
* (note: "prepositional phrase" is also a type, but it's not primitive because we make it using other types)
* a data object is like "over the hill", it's an instantiation of a prepositional phrase (which is both a data
structure and data type)
>What I want to do is say that yes those are all the same thing, and that they are data types that are built into a
>programming language. But I’ve got too many unanswered questions to do that yet.
I wrote a bit about data types, data structures, and data objects if anyone is curious:
>This confirms that pairs are “primitive datatypes” in Scheme. Are “primitive data structure”, “primitive data object”,
>and “primitive datatype” all the same thing? I don’t know.
This sort of naming can change from language to language, but I would expect something like:
datatypes and data structures to be very similar or actually the same thing. A data structure is almost always referring
to non-primitives, particularly the stuff we have to implement in the language like a 'linked list'. data structures are
constructed in certain ways and have certain operations which are fast and slow (specific to the data structure). The
map I described above is a data structure.
A data *type* (or datatype) is either a conceptual thing like "a list of lists" or the name of the type
within the language, like "integer". Scheme is dynamically typed so the closest you get are the predicates you quoted
like `boolean?`, `pair?`. Other languages (which are statically typed) have explicit type systems that require you to
explicitly define new types you create (sort of like you define functions).
A data *object* is almost certainly talking about the *instantiation* of something with particular properties. It can
be used more generally too.
--
Max
xk.io
I post my FI work/articles/exercise/practice here:
https://xertrov.github.io/fi