Comments (6)
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.
from lens.
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.
from lens.
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?
from lens.
@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.
from lens.
Ah, I see the problem now. That revised contract makes sense to me.
from lens.
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.
from lens.
Related Issues (20)
- Add isomorphism between positive integers and lists of digits
- struct->vector isomorphism HOT 5
- lens-zoom examples shouldn't use isomoprhism lenses
- Add digit->char isomorphism
- There should be a test for the cond-lens error case.
- There should be a test for the string-split-lens case where the input violates the lens laws HOT 2
- struct->struct lens? HOT 1
- Rethink unstable collection? HOT 2
- Test `lens-compose` / `compose` relationship HOT 1
- using append* n times vs. flattening a nested list of a given depth HOT 9
- Matrix lenses? HOT 2
- Disarm and re-arm syntax objects within srcloc-lens setters HOT 1
- Modulo lens HOT 3
- Struct inheritence and lenses HOT 32
- separate tests into `lens-test` repository HOT 13
- Add prisms or other functionality that tests a lens's applicability HOT 4
- lens-join/* functions produce non-lenses when views overlap HOT 2
- Docs: Is the "last set wins" law right (strong enough)? HOT 3
- Waffle.io has closed HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lens.