C++ compile-time enum to string, iteration, in a single header file
Functional HTML scraping and rewriting with CSS in OCaml
Code coverage for OCaml and Reason
aantron/luv 178
Cross-platform asynchronous I/O and system calls
A tail-recursive list map with good performance for all list sizes. Not actually written in assembly.
OCaml binaries for all the platforms
Bisect_ppx + BuckleScript starter repo
Bisect_ppx + esy starter repo
aantron/bisect-ci-integration-megatest 1
Code coverage for OCaml and Reason: web integrations testing
pull request commentocsigen/lwt
I think, in the worst case, you should be able to define the function using higher-level helpers like on_cancel. I could be wrong. But if that's correct, I suggest to go that route rather than introducing a new internal constructor.
comment created time in 4 hours
pull request commentocsigen/lwt
String_val returns const char *
Thanks @dra27.
I agree. We should aim to change Lwt to use the -W functions on Windows, as you suggest, in the long term (if this isn't superseded by libuv conversion or some other such work).
For right now, I think the best thing to do is cast, and add a comment that this is only valid because we are calling CreateProcessA, perhaps with links to this PR, the blog post, and/or the MSDN entry. Or we can change this specific code to call CreateProcessW, as in the code @dra27 linked.
comment created time in 12 hours
push eventocsigen/lwt
commit sha d6fcacf89ea065904469b9bfae91fdb19db8424f
Add Lwt_main.abandon_yielded_and_paused Resolves #789.
push time in a day
issue closedocsigen/lwt
Lwt_unix.fork not canceling pending promises
The documentation Lwt_unix.fork claims that
in the child process all pending jobs are canceled
However it seems it is not entirely the case, as demonstrated by the example bellow. In this example I fork processes in a parallel iteration over a list. I expect that only the main process forks new jobs, however some forked processes do fork again while they obviously shouldn't.
With sequential iteration on the list, the problematic behavior does not happen.
Warning: Don't increase the size of the list, it rapidly leads to a fork bomb that exhausts available pids which crashes the system.
Tested with Lwt 4.2.1(ocaml 4.07.1) and 5.3.0 (ocaml 4.10.0).
open Lwt
let ( -- ) i j = List.init (j - i + 1) (fun x -> x + i)
let main_pid = Unix.getpid ()
let fork_one i =
Lwt_io.flush_all () >>= fun () ->
if Unix.getpid () <> main_pid then
Format.printf
"Error: Forking from non-main process %d (%d in the list) child of %s@."
(Unix.getpid ())
i
(let ppid = Unix.getppid () in
if ppid = main_pid then "main" else string_of_int ppid) ;
match Lwt_unix.fork () with
| 0 -> Lwt_unix.sleep 0.1 >>= fun _ -> exit 0
| pid ->
Format.printf "%d forked from %d@." pid (Unix.getpid ()) ;
Lwt_unix.waitpid [] pid >>= fun _ -> Lwt.return_unit
let fork_many i = Lwt_list.map_p fork_one (0 -- i)
let _ =
Format.printf "Main process pid is %d@." (Unix.getpid ()) ;
Lwt_main.run (fork_many 3)
closed time in a day
picojulienpush eventocsigen/lwt
commit sha b41d85411a80ae9555e1c7e81170890782689e0b
Clarify Lwt_unix.fork docs Part of #789. [skip ci]
push time in a day
issue closedocsigen/lwt
dune top loads lwt/unix/lwt_unix.cma which starts event loop
I'm trying to leverage dune toplevel integration (docs: https://dune.readthedocs.io/en/stable/toplevel-integration.html), my project is using lwt, and somewhere in the middle of generated output from dune top there is the following line:
#load "/home/vagrant/git/ocaml/my-project/_opam/lib/lwt/unix/lwt_unix.cma";
Both utop and rtop hang on this. I've launched rtop in gdb, and hitting ctrl+c gives the following backtrace after rtop "hangs":
Reason # #use_output "cat foo.ml";
[Detaching after fork from child process 5513]
^C
Thread 1 "ocamlrun" received signal SIGINT, Interrupt.
0x00007ffff7d507ef in epoll_wait (epfd=3, events=0x5555555d3de0, maxevents=64, timeout=59743) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30
30 ../sysdeps/unix/sysv/linux/epoll_wait.c: No such file or directory.
(gdb) bt
#0 0x00007ffff7d507ef in epoll_wait (epfd=3, events=0x5555555d3de0, maxevents=64, timeout=59743) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30
#1 0x00007ffff70cd873 in ?? () from /lib/x86_64-linux-gnu/libev.so.4
#2 0x00007ffff70cfcde in ev_run () from /lib/x86_64-linux-gnu/libev.so.4
#3 0x00007ffff70eced8 in ev_loop (flags=2, loop=0x5555555d3870) at /usr/include/ev.h:836
#4 lwt_libev_loop (val_loop=<optimized out>, val_block=<optimized out>) at lwt_libev_stubs.c:102
#5 0x0000555555583222 in caml_interprete (prog=0x7ffff710f010, prog_size=<optimized out>) at interp.c:908
#6 0x0000555555585ac2 in caml_main (argv=0x7fffffffde78) at startup_byt.c:448
#7 0x00005555555686cc in main (argc=<optimized out>, argv=<optimized out>) at main.c:44
So it seems that it started the event loop. That does not seem to be the intended behavior :)
closed time in a day
Lupuspull request commentocsigen/lwt
String_val returns const char *
MSDN has:
The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
Given the typical representation of strings in OCaml, do we ever end up in an environment where CreateProcess is CreateProcessW? I guess this is a question for anyone watching the repo. @dra27?
MSDN is silent on whether either CreateProcess function can write into lpEnvironment.
comment created time in a day
Pull request review commentocsigen/lwt
let protected_tests = suite "protected" [ ] let suites = suites @ [protected_tests] +let cancelable_tests = suite "wrap_in_cancelable" [+ test "fulfilled" begin fun () ->+ let p = Lwt.wrap_in_cancelable (Lwt.return ()) in+ Lwt.return (Lwt.state p = Lwt.Return ())+ end;++ test "rejected" begin fun () ->+ let p = Lwt.protected (Lwt.fail Exception) in+ Lwt.return (Lwt.state p = Lwt.Fail Exception)+ end;++ test "pending(task)" begin fun () ->+ let p, _ = Lwt.task () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.return (Lwt.state p = Lwt.Sleep && Lwt.state p' = Lwt.Sleep)+ end;++ test "pending(task), fulfilled" begin fun () ->+ let p, r = Lwt.task () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.wakeup r "foo";+ Lwt.return (Lwt.state p = Lwt.Return "foo" && Lwt.state p' = Lwt.Return "foo")+ end;++ test "pending(task), canceled" begin fun () ->+ let p, _ = Lwt.task () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.cancel p';+ Lwt.return (Lwt.state p = Lwt.Fail Lwt.Canceled && Lwt.state p' = Lwt.Fail Lwt.Canceled)+ end;++ test "pending(wait)" begin fun () ->+ let p, _ = Lwt.wait () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.return (Lwt.state p = Lwt.Sleep && Lwt.state p' = Lwt.Sleep)+ end;++ test "pending(wait), fulfilled" begin fun () ->+ let p, r = Lwt.wait () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.wakeup r "foo";+ Lwt.return (Lwt.state p = Lwt.Return "foo" && Lwt.state p' = Lwt.Return "foo")+ end;++ test "pending(wait), canceled" begin fun () ->+ let p, _ = Lwt.wait () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.cancel p';+ Lwt.return (Lwt.state p = Lwt.Sleep && Lwt.state p = Lwt.Fail Lwt.Canceled)+ end;++ test "pending(task), canceled, fulfilled" begin fun () ->+ let p, r = Lwt.task () in+ let p' = Lwt.protected p in+ Lwt.cancel p';+ Lwt.wakeup r "foo";+ Lwt.return+ (Lwt.state p = Lwt.Fail Lwt.Canceled && Lwt.state p' = Lwt.Fail Lwt.Canceled)+ end;++ test "pending(wait), canceled, fulfilled" begin fun () ->+ let p, r = Lwt.wait () in+ let p' = Lwt.protected p in+ Lwt.cancel p';+ Lwt.wakeup r "foo";+ Lwt.return+ (Lwt.state p = Lwt.Return "foo" && Lwt.state p' = Lwt.Fail Lwt.Canceled)+ end;++ (* Implementation detail: [p' = Lwt.wrap_in_cancelable _] can still be+ resolved if it becomes a proxy. *)+ test "pending, proxy" begin fun () ->+ let p1, r1 = Lwt.task () in+ let p2 = Lwt.wrap_in_cancelable p1 in++ (* Make p2 a proxy for p4; p3 is just needed to suspend the bind, in order+ to callback the code that makes p2 a proxy. *)+ let p3, r3 = Lwt.wait () in+ let _ = Lwt.bind p3 (fun () -> p2) in+ Lwt.wakeup r3 ();++ (* It should now be possible to resolve p2 by resolving p1. *)+ Lwt.wakeup r1 "foo";+ Lwt.return (Lwt.state p2 = Lwt.Return "foo")+ end;+]+let suites = suites @ [protected_tests]
This should append cancelable_tests, not protected_tests.
comment created time in a day
Pull request review commentocsigen/lwt
let protected_tests = suite "protected" [ ] let suites = suites @ [protected_tests] +let cancelable_tests = suite "wrap_in_cancelable" [+ test "fulfilled" begin fun () ->+ let p = Lwt.wrap_in_cancelable (Lwt.return ()) in+ Lwt.return (Lwt.state p = Lwt.Return ())+ end;++ test "rejected" begin fun () ->+ let p = Lwt.protected (Lwt.fail Exception) in+ Lwt.return (Lwt.state p = Lwt.Fail Exception)+ end;++ test "pending(task)" begin fun () ->+ let p, _ = Lwt.task () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.return (Lwt.state p = Lwt.Sleep && Lwt.state p' = Lwt.Sleep)+ end;++ test "pending(task), fulfilled" begin fun () ->+ let p, r = Lwt.task () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.wakeup r "foo";+ Lwt.return (Lwt.state p = Lwt.Return "foo" && Lwt.state p' = Lwt.Return "foo")+ end;++ test "pending(task), canceled" begin fun () ->+ let p, _ = Lwt.task () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.cancel p';+ Lwt.return (Lwt.state p = Lwt.Fail Lwt.Canceled && Lwt.state p' = Lwt.Fail Lwt.Canceled)+ end;++ test "pending(wait)" begin fun () ->+ let p, _ = Lwt.wait () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.return (Lwt.state p = Lwt.Sleep && Lwt.state p' = Lwt.Sleep)+ end;++ test "pending(wait), fulfilled" begin fun () ->+ let p, r = Lwt.wait () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.wakeup r "foo";+ Lwt.return (Lwt.state p = Lwt.Return "foo" && Lwt.state p' = Lwt.Return "foo")+ end;++ test "pending(wait), canceled" begin fun () ->+ let p, _ = Lwt.wait () in+ let p' = Lwt.wrap_in_cancelable p in+ Lwt.cancel p';+ Lwt.return (Lwt.state p = Lwt.Sleep && Lwt.state p = Lwt.Fail Lwt.Canceled)+ end;++ test "pending(task), canceled, fulfilled" begin fun () ->+ let p, r = Lwt.task () in+ let p' = Lwt.protected p in+ Lwt.cancel p';+ Lwt.wakeup r "foo";+ Lwt.return+ (Lwt.state p = Lwt.Fail Lwt.Canceled && Lwt.state p' = Lwt.Fail Lwt.Canceled)
What causes p to become canceled here? IIRC protected should prevent propagation of cancellation from p' to p.
comment created time in a day
pull request commentocsigen/lwt
Thanks!
IMO it's not worth it.
[On adding a new function] I agree.
I added a note in the CHANGES file, not sure if that's how you want to keep track of it. If not let me know and I can remove that part.
I usually write/rewrite the changelog right before release, so this is fine :)
How strongly should I encourage people to use
pauserather thanyield? Do we want to deprecateyieldaltogether or just point atpause?
It would probably be too noisy to attach a deprecation annotation to it, so I think the way you have the docs recommend pause in this PR is best.
comment created time in a day
push eventocsigen/lwt
commit sha 0f532e5f341be58b816d7ae596fc075cdb93aee5
Document `Lwt_main.yield` encouraging the use of `Lwt.pause`
commit sha 860c7e0f0a283dda49079420d73ce12795155710
Avoid some double reversings in Lwt_list
push time in a day
PR merged ocsigen/lwt
Two relatively simple modifications. (Albeit one is simple but not trivial.)
The first commit implements Lwt_main.yield as a call to Lwt.pause and removes all the support code associated with the previous implementation. This is not trivial and may have subtle effects on the scheduling performed in Lwt_main.run.
The second commit simply avoids some List.rev calls when traversing lists (iter_p, iteri_p, etc.).
pr closed time in a day
push eventaantron/bisect-ci-integration-megatest
commit sha 27d984c290872a4006653281437855d89ffbc33f
Scheduled build (cron)
push time in 5 days
push eventaantron/markup.ml
commit sha 7e2adca8389543b8a7335a12c57bff38a797640a
Tweak README [skip ci]
push time in 6 days
push eventaantron/markup.ml
commit sha de9eb2bafe87cf62f5e7aa87adfe890c756c8159
Tweak README [skip ci]
push time in 6 days
issue closedaantron/markup.ml
Original <body> is lost when body tag is emitted due to illegal tag in <head>
Consider the following document:
<!doctype html>
<html>
<head>
<img>
</head>
<body class='cls'>
</body>
</html>
The browser parses this as containing a body with class cls. (JSFiddle)
When using Markup.ml the attributes on the body tag are lost because a replacement body tag seems to be generated because of the img in the head.
This is unfortunate, because in my use case the body element has structured data attributes that I want to extract.
I've added an incomplete start to a test case on my branch body-attrs-after-bad-head, but I don't really know how to resolve this without losing the desirable semantics of generating a body tag if it is missing altogether.
Hope you have some ideas. Thanks for your time.
closed time in 6 days
apescharissue commentaantron/markup.ml
Original <body> is lost when body tag is emitted due to illegal tag in <head>
The Markup.ml part of this was addressed by @apeschar in #55. Thanks again!
comment created time in 6 days
pull request commentaantron/markup.ml
Report attributes with `Misnested_tag
Thanks!
I didn't add the attributes to the error message, which is confusing when different errors are compared in the tests (the messages are the same).
That's probably fine for now. If it becomes confusing, I would suggest
misnested tag: 'body' in 'body'
misnested tag: 'body' with 1 attribute in 'body'
misnested tag: 'body' with 2 attributes in 'body'
to keep the error message length reasonable while still calling the user's attention to what is the likely source of difference in comparison.
comment created time in 6 days
push eventaantron/markup.ml
commit sha 980c182e7844d7e2043043604874828c10acfb57
Report attributes with `Misnested_tag (#55)
push time in 6 days
PR merged aantron/markup.ml
The helper saves a lot of typing and sometimes an extra variable (name).
I didn't add the attributes to the error message, which is confusing when different errors are compared in the tests (the messages are the same).
This could work?
misnested tag: 'body' in 'body' with attributes 'class' = 'whatever', 'id' = 'something'
pr closed time in 6 days
issue commentaantron/markup.ml
Original <body> is lost when body tag is emitted due to illegal tag in <head>
we could extend markup.ml to include attribute data in the error, and Lambda Soup to propagate attributes on misnested body elements to the generated body element using
~report.
That seems right.
We can define
`Misnested_tag of string * string * (string * string list), or`Misnested_tag of Token_tag.t * string.
At least at first glance, I prefer the former, for two reasons:
- To avoid exposing an extra type or type abbreviation in the interface.
Token_tag.t, in particular, has an additionalself_closingfield, and may have other fields that are not meant for the user to depend on. In general, it's an internal type and I'd like to retain the ability to change it at will, in principle.
As for the syntax in the source code of Markup.ml itself, it seems that we can get the shorter syntax by just defining a helper that will take the right parts out of t anyway, though I probably would first just use patterns like in your second example, until I became convinced that it is too annoying to do it that way :)
comment created time in 7 days
issue commentaantron/markup.ml
Original <body> is lost when body tag is emitted due to illegal tag in <head>
This is caused by a limitation of Markup.ml's design, namely that Markup.ml is a streaming parser (it deliberately does not parse the whole document before emitting signals). In contrast, HTML5 specifies a non-streaming parser that has access to the entire DOM tree throughout parsing, and can make non-local modifications to elements based on input that occurs much later than the input which created the elements. The conversion to streaming is mostly faithful, but there are a few cases (I recall three) where a correct conversion is impossible, all because they would inherently require reading the whole document in order to emit a given element correctly:
-
Nested (explicitly or due to error recovery)
<body>elements, as in this issue. The spec requiresfor each attribute on the token, check to see if the attribute is already present on the
bodyelement (the second element) on the stack of open elements, and if it is not, add the attribute and its corresponding value to that element. -
Nested
<html>elements, for the same kind of reason. -
Certain bad
<table>inputs.
This is described with much less detail in Conformance status.
My idea for addressing this was to change the parser to emit richer nesting errors, so that a user who is building a DOM can implement the non-local correction themselves. It is already possible to observe the errors emitted by the parser by using the ?report argument of parse_html:
Markup.(parse_html
?report:(fun location e -> prerr_endline (Error.to_string ~location e))
input
I think Error.t can be extended to carry attribute information, which can then be included when reporting the nested body tag here:
https://github.com/aantron/markup.ml/blob/6d082308caa9ef01894e5d2d0485b1d16b58f2be/src/html_parser.ml#L1647-L1648
I'd probably also add a helper that can implement the spec's check
for each attribute on the token, check to see if the attribute is already present on the
bodyelement (the second element) on the stack of open elements, and if it is not, add the attribute and its corresponding value to that element.
by walking along two attribute lists, but maybe this isn't so useful, as it depends on the user's DOM representation. At least, I would document what should be done in this case according to the spec (which the user can choose to ignore if they want to).
comment created time in 7 days
issue commentaantron/promise
About the deprecation of the infix operators
Thanks! I am happy to leave them in and not deprecate them.
comment created time in 9 days
issue commentocsigen/lwt
Avoid dependencies on compatibility modules when possible
Ok, convinced :) I will merge a PR doing this.
comment created time in 10 days
issue commentocsigen/lwt
Avoid dependencies on compatibility modules when possible
Thanks.
Thinking about the various effects of this, it occurs to me that we might break some users who expect Result or Seq to be transitively pulled in, if they start compiling on high-enough versions of OCaml.
The conditional Dune file is fine, since it will already be conditional in Lwt until the minimum supported OCaml version is 4.08, and the branch only adds conditions on 4.03 and 4.07.
comment created time in 10 days
pull request commentocsigen/lwt_ssl
add close_notify as raw SSL_shutdown
LGTM. I suppose we should wait for https://github.com/savonet/ocaml-ssl/pull/63 and a release of ssl before merging this, so we can add the right constraint here. If you agree, please ping this PR when ssl is released.
comment created time in 11 days
issue commentocsigen/lwt
Avoid dependencies on compatibility modules when possible
What's the motivation for using (implicit_transitive_deps false) in Mirage?
comment created time in 11 days
pull request commentaantron/bisect_ppx
WIP: Port the ppx from omp to ppxlib
I see that this makes Bisect_ppx transitively depend on Base. From discussions with @jeremiedimino and @rgrinberg, I got the impression that Base would eventually not be a dependency of ppxlib or other future PPX helper library. Is that still the case? I strongly prefer not to introduce Base as a dependency of Bisect_ppx.
comment created time in 12 days
pull request commentaantron/bisect_ppx
WIP: Port the ppx from omp to ppxlib
BuckleScript support should work with this approach, as for BuckleScript support, we build the Bisect_ppx binaries using the opam ecoystem (though using esy as the package manager). However, it is broken in this PR at the moment: https://travis-ci.org/github/aantron/bisect_ppx/jobs/710719501.
Travis seems to not be reporting status to GitHub (a problem they have been having on and off for months now). The builds are running, however. They are at https://travis-ci.org/github/aantron/bisect_ppx.
comment created time in 12 days
pull request commentaantron/luv
I won't have time to properly review this until probably the next libuv release, but I do want to include it. Would you mind letting the 0.5.4 release proceed? I wasn't explicitly trying to support FreeBSD as of 0.5.4, but I will support it in future releases.
comment created time in 13 days
push eventaantron/luv
commit sha 4f9ba828d955288fb6c280d70f7ace800c6d0da9
Add S_IFREG to Luv.File.Mode (#73)
push time in 20 days
PR merged aantron/luv
Missed the S_IFREG constant in https://github.com/aantron/luv/pull/69 - this adds it, so that Luv.File.stat can be used to check if the stat result represents a file.
pr closed time in 20 days
pull request commentaantron/luv
Also, the Windows build is failing. It's not due to any of the warnings in the log (those are caused by Ctypes and are not fatal). My first guess is it is due to gmake perhaps not being available in typical Cygwin environments, such as the one used by opam-repository-mingw and the one distributed by esy. I'm not sure if that's properly a Dune issue (of which command it chooses to run), but I couldn't release Luv with a newly-broken Windows build in any case.
comment created time in 21 days
pull request commentaantron/luv
I am using Travis, for fast feedback. Travis is probably just having issues reporting status at the moment, which it seems to have had several times over the last few months, or it's something else I have to look at again. Could you restore the previous Travis rows?
comment created time in 21 days
PR opened ocaml/opam-repository
- Upgrade libuv to 1.38.1 (aantron/luv#71).
- Bind
S_IFMT,S_IFDIR,S_IFBLK,S_IFCHR,S_IFLNK,S_IFIFO(aantron/luv#69, Bryan Phelps).
pr created time in 22 days
issue closedaantron/luv
See https://github.com/libuv/libuv/releases/tag/v1.38.1.
closed time in 22 days
aantronissue commentaantron/luv
Done in 2b8b37d43e472247e9c1963e63759689eae91299.
comment created time in 22 days
push eventaantron/luv
commit sha 2b8b37d43e472247e9c1963e63759689eae91299
Upgrade libuv to 1.38.1 and bump to 0.5.4
push time in 22 days
issue commentaantron/markup.ml
Some HTML is parsed incorrectly
Yes, this is the correct behavior according to the spec :)
The spec asks a compliant parser to sometimes produce outputs that may be counterintuitive. That's the result of trade-offs that were made in order to intuitively parse certain other malformed inputs that the authors of HTML5 found to be more common or otherwise important. This issue is, unfortunately, one of the cases that got "penalized" by these trade-offs.
comment created time in 22 days
issue openedaantron/luv
See https://github.com/libuv/libuv/releases/tag/v1.38.1.
created time in 22 days
issue commentaantron/markup.ml
Some HTML is parsed incorrectly
I would be happy to review a fix. The only thing to be careful of is that it complies with the HTML5 spec. Here are some relevant pieces:
- https://www.w3.org/TR/html52/syntax.html#attribute-value-double-quoted-state
- https://www.w3.org/TR/html52/syntax.html#the-in-body-insertion-mode
Are you sure that it is the newline inside the href specifically that is causing the problem? There is also a newline at the end of your input. Is that newline present in both of your tests?
My first guess as to what is happening here is that the unclosed <a> spanning the end of <p> is triggering the "reconstruct the active formatting elements" algorithm (called on by the in body insertion mode rules I linked to above). That causes formatting elements like <a> to be duplicated in multiple block elements like <p> or <body> if the formatting elements are unclosed, and there is any more input, like that final newline.
If that's correct, then this result is according to the spec (i.e. Chrome and other browsers would produce the same interpretation). Have you tried your inputs in a browser, inspecting the resulting DOMs?
You can also try parse5 online on this input: https://astexplorer.net/#/gist/e4a59515f46e8d7a1ae7ea5286730c30/341f1f298e3ce58e377ff13f497424c36fce818d. If you expand the AST, you will see that parse5 produces the same output, and the "duplication" depends on the final newline. The choice of parse5 is important, because most other JS HTML parsers (all that I have checked) don't actually comply with HTML5, and only parse an HTML-like input language without the full error recovery specified in HTML5.
comment created time in 22 days
issue commentaantron/bisect_ppx
@hannesm It is currently waiting for the release of https://github.com/ocaml/dune/pull/3535 :)
comment created time in a month
pull request commentaantron/luv
Pin the versions of the actions
Thanks!
comment created time in a month
push eventaantron/luv
commit sha 54b0860397dc3bfaf430fa7ca0716554fbfc9124
Update ci.yml (#70)
push time in a month
PR merged aantron/luv
pr closed time in a month
issue commentocsigen/lwt
dune top loads lwt/unix/lwt_unix.cma which starts event loop
This is most likely caused by utop. As I understand it, it has some special integration with Lwt_main. In addition, it might use Lwt_main internally for its own purposes. I'm not immediately familiar with the details, so I suggest to report the issue at utop (and please cc :)).
comment created time in a month
push eventaantron/bisect-ci-integration-megatest
commit sha 359aea327c0bc2114010fd53e7525d1a3ba707b3
Scheduled build (cron)
push time in a month
issue commentaantron/bisect_ppx
Support Cobertura output format
This example might help with adapting Cobertura to OCaml.
comment created time in a month
issue commentaantron/bisect_ppx
Support Cobertura output format
For future reference, here is example Cobertura output and the DTD. It seems considerably more complex that Coveralls format, and seems to make more assumptions about the source language.
comment created time in a month
issue commentaantron/bisect_ppx
Typechecking issue with GADTs under or-patterns
let ___bisect_matched_value___ = x in match x with ...
This would have to be
let ___bisect_matched_value___ = x in
match ___bisect_matched_value___ with ...
to avoid repeating side effects caused by evaluation of x. However, it still doesn't quite work, because x might raise exceptions that are intended to be handled in exception cases of the match.
There may be a solution like
match x with
| exception ___bisect_matched_value___ ->
(match ___bisect_matched_value with
...)
| ___bisect_matched_value___ ->
(match ___bisect_matched_value with
...)
I'll consider it more this week.
comment created time in a month
push eventaantron/luv
commit sha 930f50a067bde29504b7acef84fe516f93165a6d
Project documentation
push time in a month
pull request commentocaml/opam-repository
I updated the release.
comment created time in a month
push eventaantron/opam-repository-fork
commit sha 54a224c5e3859005c8978ac0792997575abf0056
Retag release
push time in a month
issue commentaantron/promise
The above commit further reduced the compiled size, to 1099 bytes. This version of the library is now in npm as [email protected].
As an interesting factoid, when it comes to the source size, 60% of the published npm package is the library README :)
comment created time in a month
push eventaantron/promise
commit sha 8a2f2922eec690311de598df2412c4bcb5f9a135
Bump to 1.1.1 [skip ci]
push time in a month
push eventaantron/promise
commit sha 7b7656c62a7a29f06383aa9b4c6ae521d5ac82ef
Reduce code size of allOk* functions Resolves #57.
push time in a month
issue closedaantron/promise
See https://github.com/aantron/promise/issues/54#issuecomment-646112858. It is currently a bit under 4K over 1K (thanks @cknitt), up from an earlier ~950 bytes, but, per the linked comment, there is likely a lot of the new stuff that can be easily reduced.
closed time in a month
aantronpush eventaantron/promise
commit sha 41082f6a505dab9fff1c74b69cbca00d5f7bbeda
Reduce code size of allOk* functions Resolves #57.
push time in a month
pull request commentocaml/opam-repository
Promise 1.1.0 - native version of a JS Promise binding
Thanks. That should be fixed in the new archive.
comment created time in a month
push eventaantron/opam-repository-fork
commit sha b93cad5fc9f4132151e963f556d677a9f552c89b
Update checksum for re-release
push time in a month
push eventaantron/promise
commit sha 94e76e0267413f1ca6ce60112ca96d86f375c1c2
Native: fix usage of Result
push time in a month
push eventocsigen/lwt
commit sha c00934439e5f72fdc9ad89efe601cb10d6cabded
Remove GitHub Sponsors
push time in a month
issue commentaantron/promise
After #58 by @cknitt replaced Array fully by Belt.Array, the compiled size is 1184 bytes
comment created time in a month
pull request commentaantron/promise
Travis CI status reporting seems to be broken for PRs at the moment. There are several bug reports like this one at Travis with no satisfactory solution yet. The builds are running, though, e.g. https://travis-ci.org/github/aantron/promise/builds/700295405 ran for this PR.
comment created time in a month
pull request commentaantron/promise
Thanks! This decreased the incremental (that is, compared to someone already using Belt) compiled size from 3913 bytes to 1184 bytes.
comment created time in a month
push eventaantron/promise
commit sha 0fb6c9385309031ed9a4a9219f364e068e421b5d
Use Belt everywhere. (#58)
push time in a month
PR merged aantron/promise
As discussed in #57, make sure that on the JS side we import only belt_Array.js and not caml_array.js, too.
pr closed time in a month
push eventaantron/promise
commit sha 8388287c7cda327c757bdcec0ba3a9ac964cb659
Add .bsb.lock to .gitignore. (#60)
push time in a month
issue commentaantron/promise
Yes.
- When I last tried refmt (admittedly, ~2 years ago), I found it made the code much less legible to me. Among other things, it butchers the consistency of the
.reifile for the many repetitive functions, by formatting them only locally according to the lengths of the tokens in each function signature. - Outside contributors are so rare that I found using a global "blind" format not worth the tradeoff in light of (1).
See also #48.
comment created time in a month
issue commentaantron/promise
Promise.allOk and its variations
Not with memory safety. In that pseudocode, the function that is directly called on each promise is then. So if promises is [p1, p2], the code will attach a callback to p1 and the same callback to p2. If p1 resolves with Error(_), the "final" promise of allOk gets resolved with Error(_), but there is no way to eagerly remove the callback on p2 — it can only be removed when p2 also resolves. So that would be a memory leak. The pseudocode might work if promises had some kind of intelligent transitive callback removal scheme, so that fast-fail in race triggered callback removal for everything passed to all, which then triggered callback removal for everything passed to each then. But to my knowledge, no promise implementations do that. I'm not sure if such a scheme could be correct, predictable, performant, etc.
I believe the function that is directly called on p1 and p2 has to be race, because it is the only function that has fail-fast behavior, which, if implemented correctly without memory leaks, should remove callbacks it added to promises that haven't resolved. The only other case in which this happens in JS promises is all in case of rejection, but reason-promise doesn't use rejections, except at the binding level in module Promise.Js, and, anyway, it wouldn't help, because resolving with Error(_) is not a rejection at the JS level :) So that all leaves race as the only choice for a function to call directly on the user's promises.
comment created time in a month
issue commentaantron/promise
Thanks, good catch. I chose Array for this initial version so I could write the same code for native and JS in limited time :) I'll solve this issue in a week or two and do a follow-on release.
comment created time in 2 months
push eventaantron/promise
commit sha 0b168194fd36c1b710a2cffb3ad1f8fc6821530e
Bump to 1.1.0 [skip ci]
commit sha 4ea9b7cdb3a111159570e38743a908c9af1268cb
Expand clean command [skip ci]
push time in 2 months
PR opened ocaml/opam-repository
Changelog:
- Add
allOk,allOk2...allOk6,allOkArray— fast-fail versions ofall(aantron/promise#54, requested Jay Mithani). - Compatibility with BuckleScript 8.0.0 (aantron/promise#56, reported Christoph Knittel).
pr created time in 2 months
issue openedaantron/promise
See https://github.com/aantron/promise/issues/54#issuecomment-646112858. It is currently a bit under 4K, up from an earlier ~950 bytes, but, per the linked comment, there is likely a lot of the new stuff that can be easily reduced.
created time in 2 months
issue commentaantron/promise
Promise.allOk and its variations
Also, the implementation is slightly tricky for the sake of memory safety, see this comment if interested :)
https://github.com/aantron/promise/blob/ae44bad610e222e6e5d1f6825efd8f4035f68769/src/js/promise.re#L279-L289
comment created time in 2 months
issue commentaantron/promise
Promise.allOk and its variations
The linked commit added allOk, allOk2...allOk6, and allOkArray, and these functions are now in npm as part of [email protected]. Thanks again for requesting them.
I've linked them from the docs at the bottom of the error handling section.
One side effect is that all the allOk* functions have bloated the compressed size of reason-promise from about 1K to nearly 4K. However, I think I can eliminate most of that in a future release by taking advantage of the fact that tuples are arrays, and simply unsafely defining all the allOk* functions as allOkArray, which is already the case for the plain all* functions and allArray.
comment created time in 2 months
issue commentaantron/promise
BuckleScript 8.0.0 breaks listToArray / Promise.all
The fixed version is now in npm as [email protected]. Thanks @cknitt for the report!
comment created time in 2 months
push eventaantron/promise
commit sha ae44bad610e222e6e5d1f6825efd8f4035f68769
README: point allOk* links to their live locations [skip ci]
push time in 2 months
push eventaantron/promise
commit sha 8142b0c4cb5e88e0241c3a6926fdf096b1b96935
Add Promise.allOk and its variants Resolves #54.
push time in 2 months
issue closedaantron/promise
Promise.allOk and its variations
Hi,
Thank you for this great library! I was wondering it would be possible to add Promise.allOk (i.e. a result version of Promise.all) and its variations? At the moment, I believe there is nothing provided that replicates the fail-fast behavior of JavaScript's Promise.all with the result type. Thanks for your consideration!
closed time in 2 months
jaymthpush eventaantron/promise
commit sha 863426924c502206879a8e986aad4eaf8febe40d
Adapt to BuckleScript 8.0.0: use Belt more Fixes #56.
push time in 2 months
issue closedaantron/promise
BuckleScript 8.0.0 breaks listToArray / Promise.all
The internal representation of lists changed in BuckleScript 8.0.0. Lists are now encoded as {hd, tl}, not as nested arrays anymore.
This breaks the functions listToArray and arrayToList and thereby all functions relying on them (Promise.all, Promise.race).
closed time in 2 months
cknittissue commentaantron/promise
BuckleScript 8.0.0 breaks listToArray / Promise.all
Yes, I will switch the library to the Belt functions and do a release. I don't immediately recall why I added these implementations.
comment created time in 2 months
issue commentaantron/bisect_ppx
Typechecking issue with GADTs under or-patterns
Considering your suggestion further, it may be a good way to avoid this conclusively :)
comment created time in 2 months