⚡ Sangsakala Proxy 🏠 Home
Skip to content

Deprecate then remove all unsafe API #192

Open

Description

@jbgi

or at least move unsafe API under a Unsafe nested class (or better: a separate "unsafe" artefact) with all methods prefixed with unsafe.
eg. List.tail(), List.head() should not be part of List public API.

maybe for functionaljava 5?

@functionaljava WDYT?

Activity

  1. dobesv commented on Sep 11, 2015

    @dobesv
    Contributor

    I do find myself using these regularly because Java lacks a pattern matching mechanism. I think it could be done using the visitor pattern, but List doesn't currently implement the visitor pattern. So I do something like if(x.isNotEmpty()) { ... x.head() ... } else { ... }.

    Removing or renaming these methods now would create some headaches for me, and probably others, so some kind of deprecation procedure would be recommended. I'm not sure its worth the pain right now.

  2. techtangents commented on Sep 11, 2015

    @techtangents

    dobesv mailto:notifications@github.com
    12 September 2015 8:19 am

    I do find myself using these regularly because Java lacks a pattern
    matching mechanism. I think it could be done using the visitor
    pattern, but List doesn't currently implement the visitor pattern. So
    I do something like |if(x.isNotEmpty()) { ... x.head() ... } else {
    ... }|.

    This is what folds are for.

  3. tonymorris commented on Sep 12, 2015

    @tonymorris
    Contributor

    👍

    Move unsafe functions out, so that if they are not imported, it is more clear that they are not used.

  4. jbgi commented on Oct 22, 2016

    @jbgi
    MemberAuthor

    the road block to completely removing those unsafe functions is the lack of TCO. Eg. Implementing listEqual without head() and tail() in a stack safe manner is not totally satisfying: you have to allocate objects (Option or Trampolining) at each iteration, or use some sort of mutable local function.
    But well this is Java...

  5. jbgi commented on Oct 22, 2016

    @jbgi
    MemberAuthor

    To clarify what I meant by "some sort of mutable function", here is how one could implement List.forEach without head() and tail():

    public final Unit foreach(final F<A, Unit> f) {
        final class ForEachCons implements F2<A, List<A>, Boolean> {
          List<A> as = List.this;
          @Override
          public Boolean f(A head, List<A> tail) {
            as = tail;
            f.f(head);
            return true;
          }
        }
        ForEachCons forEachCons = new ForEachCons();
        while (forEachCons.as.uncons(forEachCons, false)) {}
        return unit();
    }

    To be compared with current implementation:

      public final Unit foreach(final F<A, Unit> f) {
        for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) {
          f.f(xs.head());
        }
        return unit();
    }

    I am personally ok-ish with the former implementation but I am guessing not everyone... @functionaljava WDYT?
    or is there alternative I am not seeing?
    one of them may be to keep using head/tail for primitive recursive functions...

  6. dobesv commented on Oct 25, 2016

    @dobesv
    Contributor

    I think it's good to leave the door open to optimization. Maybe just rename
    them to have an underscore in front, so people feel a bit uncomfortable
    using them?

    On Sat, Oct 22, 2016, 4:02 AM JB Giraudeau notifications@github.com wrote:

    To clarify what I meant by "some sort of mutable function", here is how
    one could implement List.forEach without head() and tail():

    public final Unit foreach(final F<A, Unit> f) {
    final class ForEachCons implements F2<A, List, Boolean> {
    List as = List.this;
    @OverRide
    public Boolean f(A head, List tail) {
    as = tail;
    f.f(head);
    return true;
    }
    }
    ForEachCons forEachCons = new ForEachCons();
    while (forEachCons.as.uncons(forEachCons, false)) {}
    return unit();
    }

    To be compared with current implementation:

    public final Unit foreach(final F<A, Unit> f) {
    for (List xs = this; xs.isNotEmpty(); xs = xs.tail()) {
    f.f(xs.head());
    }
    return unit();
    }

    I am personally ok-ish with the former implementation but I am guessing
    not everyone... @functionaljava https://github.com/functionaljava WDYT?
    or is there alternative I am not seeing?
    one of them may be to keep using head/tail for primitive recursive
    functions...

    —
    You are receiving this because you commented.
    Reply to this email directly, view it on GitHub
    #192 (comment),
    or mute the thread
    https://github.com/notifications/unsubscribe-auth/AAUAmZEckchoX-Jfm7OU0J-efXdZWZXZks5q2e1dgaJpZM4F78GX
    .

  7. siro-mateos commented on Dec 13, 2016

    @siro-mateos
    Contributor

    I think it would also be good to give NonEmptyList more prominence (and full List methods)... for instance, List.groupBy should produce TreeMap<B, NonEmptyList<A>>.

  8. devkat commented on Feb 18, 2021

    @devkat

    +1 from me for this issue. It is hard for me to sell the library to my coworkers as a safe alternative to the Java standard library if it provides unsafe operations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions