-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Primitives #188
Comments
There's a lot to unpack in this issue. Each point you raise is going to require a detailed discussion(s). This issue probably isn't the right place for that, so let's label it as "tracking" and start discussing the finer points in our upcoming developer meetings. |
Having said that, I do want to say something here about this point:
I don't think we should be pedantic about the distinction. It wouldn't be very helpful, and the student mostly doesn't care, especially at Primer's level, where boxed values and performance are non-issues. Imagine the student wants to apply Most Schemes I know of solve the "what's the value of/how do you render a primitive function" question by choosing a special representation, e.g., |
We probably want to define as small a set of primitive functions as is feasible, implementing other useful functions in terms of those. We want to reduce the amount of "magic", and allow students to inspect function definitions. |
Yes. A good rule of thumb might be: can this function feasibly be written using pattern matching and recursion? If so, write it in Primer so that students can inspect it, step through it in the evaluator, etc. Otherwise, make it truly a primitive function that looks like a black box in the editor/evaluator. Examples of the true primitives would be most |
A few questions which have arisen while implementing #199
|
@georgefst I'm following up on things that surfaced in our last couple of Primer definition meetings. We discussed your point directly above in the 2021-12-08 meeting (notes here: https://docs.craft.do/editor/d/8b43f204-aeeb-b8ce-45cc-73a653745299/2ECD6193-27AD-4431-8A64-B317B2DD863C). It would be helpful to have an issue in GitHub to keep track of this and the solutions we've discussed (and discarded). Can you write that up when you need a break from the |
@georgefst Bumping my comment directly above. Can you write up a GitHub issue to track the implementation of partial application of multi-ary primitive functions? We should get this sorted this quarter as part of our Primer definition work. |
Here's another thing to think about: how are we going to encode primitive values as JSON? Note that our plans to switch to a JSONB encoding for |
|
Looking back at this, we've gone too far really in #233. I think we could get away with as little as We also need to revisit the primitive functions list for All of this should wait until we actually have some sort of standard library (#187), which will require a module system (#265). |
I would say that multiplication should be primitive, since it seems like a large part of the point of primitive integers is efficiency. If multiplication is defined in terms of additions, why should we not define addition in terms of successor? Having typed this, I now realise it is not very clear /why/ we want (these particular) primitives! It would be good to have some brief documentation to this effect (I'm sure we have discussed this -- capturing those ideas in an obvious place in the repo would be great!). |
Chiefly, they're a concession to instructors who want to start with a more traditional approach to learning to program (with strings and arithmetic expressions), as opposed to our preferred types-first approach. |
We currently just derive The JSON spec is clear that numbers are unbounded, so Aeson's encoding of |
yeah, I would like to use JS's new It seems to have good support (other than Internet Explorer, 'natch), but I wouldn't be surprised if some schools are stuck on browsers that don't support it. We'll deal with this when the time comes. |
We've decided that we'll need some primitive types in Primer e.g.
Int
,Float
,Char
,String
. That is, types which it wouldn't be possible for the student to define themselves, at least not in an efficient or ergonomic way. We'll also need some primitive functions (e.g.+
,intToString
,toUpperCase
...) in order for students to be able to actually do anything with our primitive types. This issue is to discuss points relevant to all primitive types. For particular types we'll open separate issues, such as #162.As a first pass, I propose that we just pre-populate the lists of types and variables with these primitives (although see below as to whether we should really consider primitive functions to be "variables"). The number of primitive functions we might need in order to make, say, strings easy to work with seem likely to clutter the UI, requiring a more sophisticated approach (see #187).
Multi-ary primitive functions are particularly interesting/awkward when it comes to evaluation in that we can only apply them to all arguments simultaneously: whereas we can reduce
(\x y -> e) $ a
to\y -> e [a/x]
, there is no such rule for+ 1
.UI/UX questions
It would be nice to treat both primitive types and values as similarly to normal expressions in the UI as possible. The major difference is that they can't be inspected. We can only really show primitive values on the canvas as a single, special "primitive" node, and similarly we can't use the existing
Inspect type
UI for types.With the design in hackworthltd/primer-app#102, we could indicate primitive types by not underlining them, and perhaps providing a tooltip explaining why they can't be clicked. Or we could allow the student to click them, but rather than displaying the
Inspect type
UI, we could show a new screen displaying information about the type. This might have:a
,b
,c
etc. but it would be far too big to fit on screen!"We may want to display similar information as above for primitive values as well. Some kind of "go to definition" functionality (hackworthltd/primer-app#113) would be useful here, so that the student can find this information easily from a primitive's use site. Otherwise we could provide it at every use site directly, perhaps in an overlay, but this seems like it could clutter the UI.
We're going to also need some support for entering primitive values (
1
,"George"
...), which will require bespoke UI components. Should these have their own action buttons e.g. "Insert a number", "Insert a character", "Insert a string"? Or perhaps a single "Insert a primitive" action with submenus, though this may require the student to know what a primitive is earlier than we'd like.Which action should we use for inserting primitive functions? In a sense they aren't really variables, since as far as the student is concerned they're indivisible - they don't reference any value and can't be inlined. But "Use a value constructor" isn't suitable either since they aren't constructors.
Should the "new session for beginners" option create a session without primitives? Whereas it's currently possible to start from this blank canvas and reconstruct all of our built-in types, this wouldn't be the case with primitives.
Implementation
@brprice has suggested that we begin by implementing a simple "primitive unit" type in order to sketch out the implementation of primitives first, without getting bogged down by details of numbers or strings. Once we have our first primitive type implemented we can then remove this.
The text was updated successfully, but these errors were encountered: