Skip to content
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

How should we name lenses for improper syntax lists? #292

Open
SuzanneSoy opened this issue Jan 5, 2017 · 6 comments
Open

How should we name lenses for improper syntax lists? #292

SuzanneSoy opened this issue Jan 5, 2017 · 6 comments
Labels

Comments

@SuzanneSoy
Copy link
Contributor

I'd like to add to the lens-data library a few lenses which help manipulating “improper syntax lists”, e.g.

(lens-view stx->list*-lens #'(a b . c)) ;; => '(a b c)
(lens-set stx->list*-lens #'(a b . c) '(1 2 3)) ;; => #'(1 2 . 3)

Also, a lens which turns an improper list into a list could be added:

(lens-view list*->list '(a b . c)) ;; => '(a b c)
(lens-set list*->list '(a b . c) '(1 2 3)) ;; => '(1 2 . 3)

Is there any convention that I should use to refer to improper lists? Or is list* a good pick?

@AlexKnauth
Copy link
Collaborator

It would be tricky to make a lens like this follow the lens laws. What should happen in an example like this?

(lens-set list*->list-lens '(a b . c) '(1 2 (3 . 4))) ;; => '(1 2 3 . 4)
(lens-view list*->list-lens '(1 2 3 . 4)) ;; => ???

The answer would be '(1 2 3 4), except that that violates one of the lens laws.

@SuzanneSoy
Copy link
Contributor Author

That's a very good point, I hadn't thought about this case. An obvious (poor) solution would be to make it a lens constructor, which takes the number of “main” elements as an argument:

(lens-set (list*->list-lens 2) '(a b . c) '(1 2 (3 . 4))) ;; => '(1 2 3 . 4)
(lens-view (list*->list-lens 2) '(1 2 3 . 4)) ;; => '(1 2 (3 . 4))

(lens-set (list*->list-lens 2) '(a b c . d) '(1 2 3)) ;; => '(1 2 . 3)
(lens-view (list*->list-lens 2) '(a b c . d)) ;; => '(a b (c . d))

This, however, is not very practical if the goal is to be able to use functions like map, length etc. on improper lists.

Another poor solution would be to contract the view with (not/c pair?), but that's annoyingly restrictive.

For my own use, I think an improper lens would be good enough, but I agree we need something better for the library.

Any suggestion? Otherwise I'll close this for now.

@jackfirth
Copy link
Owner

jackfirth commented Jan 5, 2017

Restricting the view to a proper list seems sensible to me, as the very name itself implies the target is (possibly) improper while the view is proper. In what scenarios would that restriction hinder the ability to use the lens?

@SuzanneSoy
Copy link
Contributor Author

@jackfirth The problem arises when the view is any pair, including if it's a proper list. Consider the following:

(lens-set list*->list-lens '(a b . c) '(1 2 (3 4 5))) ;; => '(1 2 3 4 5)
(lens-view list*->list-lens '(1 2 3 4 5)) ;; => '(1 2 3 4 5 ())

I made a mistake, the contract should instead be (*list/c any/c (not/c pair?)), i.e. the last element of the view should be a non-pair value (so null?, vector?, hash?, struct? etc. but not pair?), to avoid ambiguities.

In the end, the list*->list-lens is the dual of an list* lens for which the view is (apply list* target), and list* is not surjective because (equal? (list* 1 2 '(3)) (list* 1 '(2 3))), hence the ambiguity.

@jackfirth
Copy link
Owner

Ah, I see the problem now. That revised contract makes sense to me.

@jackfirth jackfirth changed the title [Question] How should we name lenses for improper syntax lists? How should we name lenses for improper syntax lists? Jan 5, 2017
@jackfirth
Copy link
Owner

As to the original question - improper list manipulation lenses in general seems like a fine addition to the library. For syntax lists specifically, ideally I'd like to see some way to express stx->list*-lens and other improper syntax list lenses in terms of list*->list-lens through some composition or combinator, to avoid a whole pile of improper list functionality that's tied up in the syntax lenses.

For naming: the a->b-lens names are generally reserved for things that are isomorphisms (which have stronger requirements than lenses) and are discussed briefly in #204 and #205. The proposed possibly-improper-list-to-proper-list lens is not an isomorphism, so some other name like list-proper-lens would be better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants