racket / rhombus-prototype Goto Github PK
View Code? Open in Web Editor NEWBrainstorming and draft proposals for Rhombus
License: Other
Brainstorming and draft proposals for Rhombus
License: Other
read
, enforest
(Honu), parse
@gus-massa
The values returned by make-custom-hash-types
and make-custom-set-types
have a different order. Change one of them to improve consistency.
Generic programming by default: map, fold, and friends are generic and not specialized to lists. - @takikawa 3 Oct 2012
MPS supports projectional editing. Should Racket2 do so too?
Use syntax parameters in for
loops for break
and continue
instead of keywords
@jackfirth
Make all of match
’s patterns properly hygienic, rather than inspecting datums for the primitive pattern-matching constructs.
from @lexi-lambda
Make every place where binding variables currently appear allow arbitrary match patterns (this requires some thought for handling what is currently things like (define (f x) ..)
, so maybe we do this in a more limited way or change that way of defining functions to use a new keyword) #41
Building on the match allowance, also allow functions to be defined case-by-case, for example maybe using a notation like this (roughly allowed in all internal definition contexts where :=
is the keyword that triggers this kind of parsing):
(length '()) := 0
(length (cons x y)) := (+ 1 (len y))
And, even better, have this turn into define/contract
or maybe provide/contract
if something like this is written:
length : (-> list? exact-nonnegative-integer?)
(length '()) := 0
(length (cons x y)) := (+ 1 (len y))
from Wishlist of backwards incompatible things for a future Racket2. #33
(Parens are required unless all the operators are identical)
A key idea, for me, is to be able to separate specifications from the code that uses them, so multiple modules can use the same specification. Here specification is types, contracts, tests, theorems that are true about the software, and so on.
I’m suggesting accessibility sight impaired and blind developers should be explicitly on the agenda
Following text was moved form https://github.com/racket/racket/wiki/Racket2
some entries below should be logged as separate issues
--
Note: This is a wishlist. There's no guarantee any of these will be in a Racket2.
Remove cond
's default else-is-void clause and replace with a default else-is-error.
Done: #39
Change match
to recognize clauses based on bindings instead of symbols, and make
it treat else
like cond
. #40 Closed as duplicate of #23
Make every place where binding variables currently appear allow arbitrary match patterns (this requires some thought for handling what is currently things like (define (f x) ..)
, so maybe we do this in a more limited way or change that way of defining functions to use a new keyword)
Done: #36
Building on the match allowance, also allow functions to be defined case-by-case, for example maybe using a notation like this (roughly allowed in all internal definition contexts where :=
is the keyword that triggers this kind of parsing):
(length '()) := 0
(length (cons x y)) := (+ 1 (len y))
And, even better, have this turn into define/contract
or maybe provide/contract
if something like this is written:
length : (-> list? exact-nonnegative-integer?)
(length '()) := 0
(length (cons x y)) := (+ 1 (len y))
Done: #41
More prefabs for basic values, especially ones like srclocs where it is useful to make cross phase
movements easy.
Done: #42
Enable internal definitions everywhere. (Note: this is tricky -- what's "everywhere"?
Eg, can define id
be followed by a definition(s) and then a value? How about in the middle
of an if
? Taken to an extreme, could definitions appear in an application form?)
#63 (possible dup of #46?)
change syntax-case to allow internal definitions (possibly by getting rid of the 'guard' section)
#64
Enable the define*
form (from racket/package
) everywhere
Done: #46
Use keywords in more places, such as unifying member
, memv
, memf
, etc. #65
Some syntax that avoids the verbosity in the keyword-apply
etc kind of functions in the common case of passing keywords around. #66
Some solution to the "no-value" value, which could be such a blessed value, or it could be a way
to say that some function accepts all the keywords as some other function. (Possibly related to
the above, of course.) #67
struct
definition macro that allows
#:auto
values#:auto
values should be something different)#:auto
fields optional keyword argumentsstruct
have a function-like form that can specify auto values as optionals and/or keywordsstruct
keyword that actually use (tagged) lists for the values, Have only either struct
or define-struct
. Not both. #68
Disallow mutation of struct
bindings. #69
Change integer?
to mean exact-integer?
. #52
Get rid of the arity-at-least
struct, and replace it with just an arity
that abstracts over the whole arity thing -- always normalizing and includes keyword arity information. Also, make it possible to always use a procedure where an arity is expected. #72
Reconsider printing and equality of mutable and immutable variants of data types (vectors,
hash tables, strings, etc.). Also reconsider the coercion of mutable vectors to immutable
vectors by datum->syntax
. #73
Add CLOS-like defmethod (with multidispatch and :before, :after, :around) on Racket classes. #74
Add interactive breakpoint in DrRacket debug. One should have REPL at breakpoint #70
Have with-output-to-string
and friends take a body, not a thunk. The current form is better named call-with-output-to-string
, in the general pattern of with-x
being syntax and call-with-x
being a procedure. #54
Have <
, >
and others take 0 or more arguments (returning #t
for the 0 and 1 argument cases). This would allow applying them to lists without fear, which would allow patterns like (define (sorted? l) (apply < l))
#53
Rename racket/cmdline
to racket/command-line
. #56
Require that macro literals always be bound. #55
Make Matthew's doc-define from ClojureWest keynote real #60
Consider having real identifiers for class/object members and use the module/namespace mechanisms to manage these references. Possibly in conjunction with a convention for names that are prefixed or included in others (so that we can have identifiers like frame%:show
treated specially). Potentially makes method invocation faster and allows static detection of method-not-found errors. #61
Have quasiquote
support ...
as well as ,@
. Among other things, this lets match
patterns can be like match
"templates" (output expressions) and be like syntax-case
etc. #62
Like string-constants-lib String constants support internationalisation via translation files so DrRacket UI can be used in a range of languages, but applied to the code.
https://en.m.wikipedia.org/wiki/Non-English-based_programming_languages
More prefabs for basic values, especially ones like srclocs where it is useful to make cross phase movements easy.
change cond else behaviour;
cond
's default else-is-void clause and replace with a default else-is-error.cond
(and match
) to use #:else
instead of else
.Racket 2 presents a good opportunity to revisit which standard library functions return mutable values and which are guaranteed to return freshly-allocated values.
Spoiler: I think more things should be immutable and freshness should rarely be guaranteed.
My particular pet issue is strings. I don't think I have ever mutated a string except to demonstrate bugs caused by the mutability of strings. I strongly suspect most other Racketeers also reason about strings as though they were immutable. Yet almost every standard library function returns mutable strings: for example, (immutable? (string-append "a" ""))
and even (immutable? (string-append "" ""))
both return #false
. I think that should change. My primary motivation is the ease of reasoning that immutable values provide, but the change might also expose additional optimization opportunities.
The question applies to other datatypes, as well. I suspect bytes may be mutated much more often than character strings, but I would still like better support for working with immutable bytes. For example, path->bytes
could return immutable bytes, or else a path->immutable-bytes
could be added. Maybe bytes-append
should return immutable bytes, or there should be an immutable-bytes-append
, or the mutability of the result should depend on the mutability of the arguments (though I personally think that would be confusing, especially in a dynamically-typed context). Basically the same trade-offs exist for vectors.
Per @dedbox's suggestion
Naming convention | Description | Example |
---|---|---|
Ends with ? |
predicates and boolean-valued functions | boolean? |
Ends with ! |
setters and field mutators | set! |
Ends with % |
classes | game-state% |
Ends with <%> |
interfaces | dc<%> |
Ends with ^ |
unit signatures | game-context^ |
Ends with @ |
units | testing-context@ |
Begins with #% |
kernel identifiers | #%app |
Has / |
"with" (a preposition) | call/cc |
Begins with make- |
generative constructors | make-pipe |
Begins with with- |
forms that have internal def body | with-limits |
Begins with call-with- |
function variants of with- |
call-with-limits |
Begins with current- |
parameters | current-compile |
Ends with =? |
equality functions | string=? |
Ends with -ref |
accessors (non-destructive) | hash-ref |
Ends with -set |
setters (non-destructive) | hash-set |
Ends with -set! |
setters (destructive) | hash-set! |
Ends with * |
variants of non-* |
let* |
Ends with /c |
contracts | list/c |
Has -> |
"to" | number->string |
Has + |
"and" | gen:equal+hash |
Begins with gen: |
generics | gen:equal+hash |
Begins with prop: |
properties | prop:procedure |
Begins with define |
definition forms | define/contract |
Ends with -values |
multiple values variants | define-values |
Begins with in- |
sequences | in-slice |
Begins with splicing- |
splicing forms | splicing-let |
?
: what about =
and <
? Should they be renamed to =?
and <?
(#16)?#%
: what about quote
, case-lambda
, let-values
? These are core forms that are not prefixed with #%
. Should there be #%
variants so that non-#%
variants can support more features (e.g., case-lambda
can handle keyword arguments)?with-
: with-input-from-file
and with-output-to-file
consume thunks rather than body (#54).collect-garbage
).splicing-begin
(#87)Let me know if I missed anything, and I will add it to the table.
Change match
to recognize clauses based on bindings instead of symbols, and make
it treat else
like cond
.
from Wishlist of backwards incompatible things for a future Racket2. #33
@jeapostrophe We have a lot of discussions in Github's Issues. Now what?
Github Issues also have labels. Can we make use of it to make organization easier?
For how to write built-in data structures with reader syntax rather than function calls. Current examples compound data literals in Racket include #hash([a . 1] [b . 2] [c . 3])
for hash tables and #(1 2 3)
for vectors.
Examples in other languages include {'a 1 'b 2 'c 3}
for hash tables in Clojure, [1 2 3]
for vectors in Clojure, (1, 2, 3)
for tuples in Haskell, and [1, 2, 3]
for lists is Haskell.
One thing I think should be considered is getting rid of auto-quoting in elements, and instead allowing expressions in elements. For example if #(elem ...)
makes vectors, #((+ 1 2))
should be equivalent to (vector 3)
and not (vector (list '+ 1 2))
.
include pattern matching forms in more binding positions (e.g. define
, let
/for
clauses) -
@samth 2 Oct 2012
Remove cond's default else-is-void clause and replace with a default else-is-error.
-taken from Wishlist of backwards incompatible things for a future Racket2. #33
We are not using IBM 704 anymore. Let's find a new name that makes more sense, and make students more relatable.
Because of an unfortunate temporary lapse of inspiration, we couldn't think of any other names for the 2 pointers in a list node than "address" and "decrement", so we called the functions CAR for "Contents of Address of Register" and CDR for "Contents of Decrement of Register".
After several months and giving a few classes in LISP, we realized that "first" and "rest" were better names, and we (John McCarthy, I and some of the rest of the AI Project) tried to get people to use them instead.
Alas, it was too late! We couldn't make it stick at all. So we have CAR and CDR.
-- Steve Russell
The current match
form has a some things that some people want to change, but can't because of backwards compatibility, such as:
patterns could be more hygienic, so list
, cons
, var
, ?
etc. should be recognized by binding, with literals instead of datum-literals
(struct cons [first rest])
(match (cons 1 '()) [(cons x y) x]) ;=> 1 instead of error
Cross-reference with #30
else
could be more like cond
's else to mark the last clause, instead of binding a pattern variable
(match #f
[1 "one"]
[else (cond [#f "absurd"] [else "else"])])
;=> "else" instead of #<void>
else
would be recognized by binding, not by datum, in accordance with (1)
identifier-patterns could be allowed if they have a match-transformer binding
(define-data List Empty (Cons first rest)) ; Empty defined as identifier match-transformer
(match (Cons 1 Empty) [Empty "empty"] [(Cons x y) x]) ;=> 1 instead of "empty"
patterns could be allowed in more binding positions, such as function parameters, let bindings, and for-iteration bindings
(let ([(list x y z) (list 1 2 3)]) x) ;=> 1
Cross-reference with #36
syntax patterns from syntax-parse could be integrated into normal match patterns
(match #'(m 1 2 3)
[#'(_ e:expr ...) #'(begin (println e) ...)])
;=> #<syntax (begin (println 1) (println 2) (println 3))>
[This doesn't seem like it has a lot of support]
patterns that use expressions within them such as app
, ?
, and ==
could be able to refer to previous pattern variables bound within the same overall pattern, like syntax-parse allows
(match (list 1 2)
[(list x (? (>=/c x) y)) y]) ;=> 2
patterns for matching keywords could be forced to use quote as in '#:kw
so that #:kw
without the quote can be reserved for special pattern syntax without introducing ambiguity
(match (list '#:kw 3) [(list '#:kw x) x]) ;=> 3
where the quote in '#:kw
is required for both the expression and the pattern
allow for defining new variables or matching new patterns in between the main pattern and a #:when
clause, similar in utility to syntax-parse's #:with pat expr
, for-loop's [id (in-value expr)]
, or data/monad do-notation's arbitrary internal-definitions in between bind clauses
(match (list 1 2)
[(list x y)
; something like `#:with z (+ x y)` or `(define z (+ x y))`
#:when (integer? z)
....])
suggested by @sorawee as part of (5) combining with syntax-parse, but it could be independent of that
Many positions in old Racket macros are not expandable, like the arguments of a lambda; whereas most positions in new macros are, like match patterns. A more exhaustive use of expanders would make the language more extensible.
<
, >
and others take 0
or more arguments (returning #t
for the 0
and 1
argument cases). This would allow applying them to lists without fear, which would allow patterns like (define (sorted? l) (apply < l))
Extracted from the old racket2 wiki. #33
I think this can be merged to racket1.
Racket2 should implement a generic API for ordered and unordered collections, something like https://github.com/lexi-lambda/racket-collections.
Drop more guarantees about new object allocations: for example, allow (append lst '())
to return lst
, and the same for other list, string, bytes, vector functions (drop 0 items from the end of a list. substring
and regexp-replace
that don't change a string, etc).
@elibarzilay 3 Oct 2012
make regexes not need double escaping
as described in http://www.greghendershott.com/2015/08/at-expressions.html
Originally from @jeapostrophe
Enable the racket/package define* form everywhere
Personally, I use define
in internal-definition context a lot. In most cases, however, I don't want letrec
, but just want let
. The reason I didn't use let
is that I want to avoid excessive indentation.
But there are cases that define
doesn't work well as a replacement for let
. E.g.,
(define (f x)
(define x (max x 0))
(* x x))
vs
(define (f x)
(let ([x (max x 0)])
(* x x)))
It would be nice if we can write:
(define (f x)
(define* x (max x 0))
(* x x))
which effectively transforms the code into the latter one. Note that it shouldn't require a wrapper macro like package-begin
over define*
.
define-values
/match-define
/match-define-values
counterparts should be provided as well.
Racket newcomers are immediately confronted with four equality operators:
equal?
, which does what you'd expect most of the time=
, which does what you'd expect if you're used to IEEE numberseq?
, which looks like "the magic fast pointer comparison / reference equality operator"eqv?
, which just looks bizarreI think we should simplify this in racket2 Rhombus. Here's a hypothetical straw proposal:
equal?
and =
eqv?
eq?
to something like same-object-reference?
and tuck it away in the corner of the docs, to make it clearer that you should only use this if you have a very good reason toIs this feasible? Can we do better?
Data goes back and forth?
Functions go back and forth?
Macros go back and forth?
Sweet
Wisp
http://breuleux.net/blog/liso.html
Honu
Remix
and many many more
In Racket 1, there are some strange rules about module paths. For example a
refers to a/main
, but a/b
doesn't refer to a/b/main
if a/b
is a directory. I also find it awkward that a/b/c
is different than (submod a/b c)
. It feels like it is exposing the "implementation" of b
.
In Racket 2, I'd like a a/b/c
is like a search path that refers to a/b/c/main.rkt
(or index
, or something similar), a/b/c.rkt
, (submod a/b c)
, (submod (submod a b) c)
, whichever exists first.
And standard-cat
.
And unify pict
with 2htdp/image
(And all the cool big-bang stuff, as well as the awesome spinoffs )
integer?
to mean exact-integer?
.Extracted from the old racket2 wiki. #33
If the old integer?
primitive were removed, how hard is to write it in racket1/racket2? Floating point calculations are sometime more tricky than expected.
(Perhaps we can collect here some similar renaming in the numerical tower.)
Right now, package dependencies are suggestions and packages don't explicitly export anything... they export everything. Both these features could be added.
For historical reasons the functions related to box
have inconsistent names with other things like hash
or vectors
. What about renaming them:
unbox
-> box-ref
set-box!
-> box-set!
new function? -> box-set
make-weak-box
-> weak-box
weak-box-value
-> weak-box-ref
make-ephemeron
-> ephemeron
ephemeron-value
-> ephemeron-ref
(?)
new function? -> ephemeron-key
(Is there a good reason to avoid this?)
The .zo and .dep files should be invisible to the user
They should be created, deleted, invalidated, and processed generally without needing to form part of the user's mental model or workflow. Look at how python does this. It'd be lovely to make explicit calls to raco make
(or even raco setup
??) unnecessary.
@tonyg
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.