smlfamily / basislibrary Goto Github PK
View Code? Open in Web Editor NEWRepository and Wiki for enriching the Standard ML Basis Library
Repository and Wiki for enriching the Standard ML Basis Library
Some curried functions in the Basis can raise exceptions. In a few cases it is underspecified when these are raised. For example, does Time.fmt ~1
throw, or is the exception deferred until the second argument is provided?
Affected functions:
This issue is for discussion of proposal 2015-001 (Correction to the ListPair module).
The option
and list
datatypes have a lot in common of each other. Both support the following operations:
(* functor *)
val map : ('a -> 'b) -> ('a t -> 'b t)
(* monoidal functor *)
val unit : 'a -> 'a t
val pair : 'a t * 'b t -> ('a * 'b) t
(* pointed functor *)
val empty : 'a t
val null : 'a t -> bool
(* monad *)
val join : 'a t t -> 'a t
The above list of operations is far from exhaustive.
Unfortunately, the API exposed by the Basis Library introduces unnecessary discrepancies:
Option
has Option.isSome
, but List
has List.null
Option
has Option.join
, but List
has List.concat
List
has List.mapPartial
, rather than List.concatMap
List
also make sense for option
s, but Option
doesn't provide themWould it be possible to fix these discrepancies?
This issue is for discussion of proposal 2022-001 (Add value tau to MATH signature).
Unsure if this is the best format/place for a new proposal (or if I should, say, create a Wiki page). If there's something else I should do, please let me know!
Often, it is useful to have access to an empty "void" type. A simple proposal might look like this:
signature VOID =
sig
type void
type t = void
val absurd : t -> 'a
end
structure Void :> VOID =
struct
datatype void = Void of void
type t = void
fun absurd (Void v) = absurd v
end
Perhaps a few other auxiliary functions could be useful, as well. For example:
val fail : string -> t (* raises `Fail` *)
val asLeft : ('a,t) either -> 'a
val asRight : (t,'a) either -> 'a
This issue is for discussion of proposal 2015-007 (Addition of Ref module).
This issue is for discussion of proposal 2015-004 (Addition of Buffer module).
This issue is for discussion of proposal 2015-005 (Addition of Fn
module).
This issue is for discussion of proposal 2015-008 (Additional math functions).
Sorry, this is a bug report, not an extension proposal.
I couldn't find a place to report a bug of basis spec.
Basis Date sais that:
Offsets are taken modulo 24 hours. That is, we express t, in hours, as sgn(t)(24*d + r), where d and r are non-negative, d is integral, and r < 24. The offset then becomes sgn(t)r and sgn(t)(24d) is added to the hours (before converting hours to days).
But sml/nj 110.97 takes an offset >24, ignore it:
- Date.toString (Date.date { year=2000, day= 1, hour=0, minute=0, month=Date.Jan, offset=SOME (Time.fromSeconds (0)), second=0});
val it = "Sat Jan 01 00:00:00 2000" : string
- Date.toString (Date.date { year=2000, day= 1, hour=0, minute=0, month=Date.Jan, offset=SOME (Time.fromSeconds (3600 * 24 + 1)), second=0});
val it = "Sat Jan 01 00:00:01 2000" : string
I think this implementation is correct, because offset larger than 24 is unnatural.
Also, the spec sais taken modulo 24 hours
.
This issue is for discussion of proposal 2015-006 (Additional string conversion functionality).
In the signature REAL, the conversion functions fromDecimal
and toDecimal
ensure that the sign
field of the IEEEReal.decimal_approx
value matches the sign bit of the real
value even if the value is NaN.
The description of the functions scan
and fromString
does not specify how the sign bit is derived in the case of an argument giving the NaN value, so an implementation may arbitrarily choose a value for the sign bit. Is this underspecified behavior intended? If the intention was to preserve the sign bit through conversion of NaN, could we say:
fromString
is equivalent to Option.composePartial (fromDecimal, IEEEReal.fromString)
?scan
is equivalent to Option.composePartial (mapPartialFirst fromDecimal, IEEEReal.scan)
fun mapPartialFirst f (a, b) = case f a of SOME a' => SOME (a', b) | NONE => NONE
?The description of the function toString
says that a NaN value is converted to the string "nan"
. This ignores the sign bit of the NaN value. Therefore toString
is not equivalent to IEEEReal.toString o Real.toDecimal
. Is this intended?
This issue is raised as suggested in smlnj/legacy#73 (comment).
This issue is for discussion of proposal 2018-001 (Addition of monomorphic buffers).
Note that this proposal is a generalization of the earlier proposal 2015-004.
I'd like interactive Successor ML implementations to expose their name as a standardized global constant:
val topLevelName : unit -> string
This way, it would be easier to work around differences between implementations, writing code that looks like this:
case topLevelName () of
"Poly/ML" => use "Foo.PolyML.sml"
| "MosML" => use "Foo.MosML.sml"
| "SML/NJ" => use "Foo.SMLNJ.sml"
Thus avoiding the need to use arcane external tools for building programs.
This issue is for discussion of the draft guidelines for SML Basis Library proposals that have been posted to the wiki.
This issue is also intended as a forum for discussing the processes needed to submit, discuss, approve, and release changes to the Basis Library.
This issue is for discussion of Proposal 2021-001 (Add getWindowSz
function to Posix.TTY
structure).
This issue is for discussion of proposal 2017-001 (Millisecond sleep).
I was curious if anyone had considered implementing signatures like VECTOR, and VECTOR_SLICE,
in terms of an opaquely ascribed cursor/iterator type, which ensures the the constraint that 0 <= i <= i + n <= |v|, where |v| is the length of v.
Then implementing the existing VECTOR/VECTOR_SLICE internally as functions from (int, cursor) -> cursor which raise Subscript exceptions when constructing the cursor to be returned, or having the cursor type transparently ascribed.
Or too much hassle for too little gain, because e.g. the lack of dependent types means 2 vectors of the same length would have to be represented by different cursor types? Mainly wanted to gauge reaction before thinking too hard about the details of implementing e.g. vector in terms of this.
Basis Date sais:
Offsets are taken modulo 24 hours. That is, we express t, in hours, as sgn(t)(24*d + r), where d and r are non-negative, d is integral, and r < 24.
r < 24
means that r is in hours.
And by we express t, in hours
, r should be integral.
But in general, the Time.time
for offset
has a finer precision than seconds.
And SML/NJ 110.97 keep values finer that hour like below:
- Date.toString (Date.date { year=2000, day= 1, hour=0, minute=0, month=Date.Jan, offset=SOME (Time.fromSeconds (0)), second=0});
val it = "Sat Jan 01 00:00:00 2000" : string
- Date.toString (Date.date { year=2000, day= 1, hour=0, minute=0, month=Date.Jan, offset=SOME (Time.fromSeconds (1)), second=0});
val it = "Sat Jan 01 00:00:01 2000" : string (* +1 sec *)
I think the specification should be modified to keep seconds.
This issue is for discussion of proposal 2018-002 (Additional slice operations).
I didn't find any issues discussing this, but guess it possibly has come up in the past,
apologies If I have missed that.
It would be convenient if many of the signatures provided by the basis came with a 'type t'.
an implementation which adds these is the extended-basis from mltonlib, but it would be nice if the basis provided them itself.
a simple use case, in the following example:
signature STRING_STUFF =
sig
type t;
val fromString: string -> t option;
val toString : t -> string;
end
functor Something(StringStuff : STRING_STUFF) =
struct
(* ... )
end
( currently you must first add the type t *)
structure IntStringStuff = struct open Int type t = int end :> STRING_STUFF;
structure Foo = Something(IntStringStuff);
(* If it was included in the basis one could just use the following instead *)
structure Foo = Something(Int :> STRING_STUFF);
given that it is possible to add these to the existing basis as mltonlib does, code like above can even be backwards compatible given a small shim, I'm not sure what if any difference it might have on compile times, if that is an argument against it, it could be measured...
This issue is for discussion of proposal 2019-001 (Correction to the PRIM_IO signature).
This is a feature request for adding regular expressions to the basic library of Successor-ML.
I assume the need for them and their usefulness is obvious, if not I could elaborate upon request.
Some SML implementations already have them.
Moscow ML has a POSIX 1003.2 variant:
http://mosml.org/mosmllib/Regex.html
SML/NJ has a variant with multiple syntaxes, currently AWK syntax:
http://www.smlnj.org/doc/smlnj-lib/Manual/regexp-lib-part.html
However lack of regular expressions in the BASIS library has dire consequences for everyday programming:
Availability - many implementations don't have them, e.g. PolyML;
Portability - a program written to use one implementation's regular expressions won't run on another's.
Which syntax will be chosen is in my opinion insignificant, but it seems like the multi-syntax approach is more versatile.
Bonus points for a direct possibility of matching a word boundary (\b or < and > in most syntaxes), a very useful feature in my experience, which both cited implementations currently lack.
Many functions only make sense when applied to nonnegative integers (e.g., List.nth
). However, because Standard ML doesn't have an unsigned integer type, one has to use signed integers, and then hopefully not forget to implement a nonnegativity check. I'd like a proper unsigned integer type, so that the check is performed automatically and at compile-time, rather than manually and at runtime.
I can anticipate an argument that I should use the existing word
type. However, as useful as the word
type may be for certain use cases (e.g., processing files with non-textual contents), it isn't a good general-purpose unsigned integer type for the following reasons:
word
constants are represented textually as hexadecimals preceded by 0w
. To get the more familiar decimal representations of numeric values, one would have to translate back and forth between word
and int
all over the place.Unsigned integers should be provided in modules with the usual INTEGER
signature, subject to the following constraints:
minInt
is always SOME 0
abs
is the identity functionsign
never returns ~1
~
raises Overflow
if its argument isn't 0
-
raises Overflow
if its first argument is less than the seconddiv
and quot
are the same functionmod
and rem
are the same functionPlease use this issue to discuss the Process document
This issue is for discussion of proposal 2015-003 (Additional operations on sequences).
An ephemeral resource is a runtime entity with nontrivial cleanup logic, which must be executed exactly once. Not more, not less. Examples of ephemeral resources are: file handles, network connections, GUI objects, etc. Java and C++ have dedicated language features (“finalizers” and “destructors”, respectively) for managing ephemeral resources. Standard ML doesn't provide any useful abstractions for this purpose, either in the core language or in the Basis Library. As a result, writing programs that don't leak ephemeral resources in Standard ML is just as hard as it is in C. What a disaster!
IMO, the most successful abstraction ever designed for managing ephemeral resources is ownership, which can be thought of as a stylized variant of substructural types. Several languages (all of which descend from C++) incorporate ownership in their design, but as far as I can tell, the only one that does so in a type-safe manner is Rust.
Of course, neither Standard ML nor Successor ML has substructural types. But that doesn't mean that we can't incorporate ownership support in some way or another. An ownership system for Successor ML must have the following properties:
Here's my very rough proposal:
This issue is for discussion of proposal 2015-002 (Addition of Either module).
This issue is for discussion of proposal 2016-001 (Add popCount to WORD signature).
Discussion of proposal 2016-003 (Conformance levels)
[Edit: This proposal only delves into the subset of the basis which is currently Required, and the portability to non-traditional kernels.]
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.