diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 62275b4b..8aff508c 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -1554,32 +1554,41 @@ (defn keys "Get the keys of an associative data structure." [x] - (def arr (array/new-filled (length x))) - (var i 0) - (eachk k x - (put arr i k) - (++ i)) - arr) + (if (lengthable? x) + (do + (def arr (array/new-filled (length x))) + (var i 0) + (eachk k x + (put arr i k) + (++ i)) + arr) + (seq [k :keys x] k))) (defn values "Get the values of an associative data structure." [x] - (def arr (array/new-filled (length x))) - (var i 0) - (each v x - (put arr i v) - (++ i)) - arr) + (if (lengthable? x) + (do + (def arr (array/new-filled (length x))) + (var i 0) + (each v x + (put arr i v) + (++ i)) + arr) + (seq [v :in x] v))) (defn pairs "Get the key-value pairs of an associative data structure." [x] - (def arr (array/new-filled (length x))) - (var i 0) - (eachp p x - (put arr i p) - (++ i)) - arr) + (if (lengthable? x) + (do + (def arr (array/new-filled (length x))) + (var i 0) + (eachp p x + (put arr i p) + (++ i)) + arr) + (seq [p :pairs x] p))) (defn frequencies "Get the number of occurrences of each value in an indexed data structure." diff --git a/src/core/corelib.c b/src/core/corelib.c index 30f417bc..383c7bc8 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -680,6 +680,13 @@ JANET_CORE_FN(janet_core_is_dictionary, return janet_wrap_boolean(janet_checktypes(argv[0], JANET_TFLAG_DICTIONARY)); } +JANET_CORE_FN(janet_core_is_lengthable, + "(lengthable? x)", + "Check if x is a bytes, indexed, or dictionary.") { + janet_fixarity(argc, 1); + return janet_wrap_boolean(janet_checktypes(argv[0], JANET_TFLAG_LENGTHABLE)); +} + JANET_CORE_FN(janet_core_signal, "(signal what x)", "Raise a signal with payload x. ") { @@ -1077,6 +1084,7 @@ static void janet_load_libs(JanetTable *env) { JANET_CORE_REG("bytes?", janet_core_is_bytes), JANET_CORE_REG("indexed?", janet_core_is_indexed), JANET_CORE_REG("dictionary?", janet_core_is_dictionary), + JANET_CORE_REG("lengthable?", janet_core_is_lengthable), JANET_CORE_REG("slice", janet_core_slice), JANET_CORE_REG("range", janet_core_range), JANET_CORE_REG("signal", janet_core_signal),