LINUX.ORG.RU

Выход mocl

 , ,


7

8

mocl — набор инструментов для разработки на Common Lisp под мобильные платформы iOS и Android. По заверениям разработчиков получаемый код (используется LLVM) по производительности значительно превосходит аналогичный на Java/Dalvik.

В основе mocl лежит идея, заключающаяся в том, что логика приложения должна быть полностью описана на Лиспе, а пользовательский интерфейс — быть «родным» для платформы. Авторы проводят аналогию с Вэбом, когда логика серверного приложения описана на одном языке (например, на Лиспе), а представление — на другом (HTML + JavaScript).

Цена лицензии варьируется от $1299 для серьёзных компаний до $199 для индивидуальных разработчиков. Также предусмотрена «Source code license» для особых энтузиастов, доступ к которой, по-видимому, дают после обращения в службу поддержки.

Пример приложения на Github.

>>> Подробности

★★★★★

Проверено: mono ()
Последнее исправление: Dendy (всего исправлений: 4)
Ответ на: комментарий от quasimoto

Это обязательное условие? Может я хочу именно их использовать.

Ну коль уж на C++. А то фиг знает там в топе чего, может там на сишке всё писано, а собрано плюсовым компилятором :)

И на сколько процентов примерно хуже, если бы они использовали родной time?

Хз. Не смотрел. Посмотрю попозже.

То есть map.

Ну да. Словарь.

З.Ы. на скале я тоже хочу попробовать, так как там вообще на ней нет. На Java есть довольно медленные, наверно ей тоже скидок не дают.

У меня есть подозрение, что у Scala вообще нет никаких шансов даже просто уложиться, даже за максимальное время как-нибудь.

BooBoo
()
Ответ на: комментарий от r

Макры в скале писались чтобы решать задачи, а не чтобы перетягивать из лиспа то что в скале нахрен не впилось.

Глупости не говори. Приведенная задача вполне себе нормальная и не привязана к языкам. Есть хороше МП — абстрагируемся от низкоуровневого разбора хеш-таблицы, нет МП — сосём. То что ты на писал на Scala, типа «извлечём нужные ключи да и определим руками связывания» — не решение нифига, т.е. «сосём».

BooBoo
()
Ответ на: комментарий от r

Фактически, то что ты пишешь руками, Lisp генерирует.

BooBoo
()
Ответ на: комментарий от BooBoo

о что ты написал — лохня, которая пишется на любом языке который сколь-нибудь в малой форме поддерживает ФП и на CL такое убожество написать — раз плюнуть

> val Day  = """([^\s]+)\s(\d?\d)""".r
> val Date  = """(\d\d)/(\d\d)/(\d\d\d\d)""".r
> val Time = """(\d\d):(\d\d):(\d\d)""".r
> val l = List(Some("11/11/2013"), None, Some("22:00:00"), Some("January 3"))


> l.map(x => x match { 
  case Some(Date(d,m,y)) => Some((d,m,y))
  case Some(Time(h,m,s)) => Some((h,m,s))
  case Some(Day(m, d)) => Some((m,d))
}).flatten

<console>:14: warning: match is not exhaustive!
missing combination           None

> l.map(x => x match { 
  case Some(Date(d,m,y)) => Some((d,m,y))
  case Some(Time(h,m,s)) => Some((h,m,s))
  case Some(Day(m,d)) => Some((m,d))
  case None => None
}).flatten

res1: List[Product with Serializable] = List((11,11,2013), (22,00,00), (January,3))

>l.view.map(x => x match { 
  case Some(Date(d,m,y)) => Some((d,m,y))
  case Some(Time(h,m,s)) => Some((h,m,s))
  case Some(Day(m,d)) => Some((m,d))
  case None => error("wtf")
}).slice(0,1).flatten.toList

res9: List[Product with Serializable] = List((11,11,2013))

Я вас очень внимательно слушаю.

r ★★★★★
()
Ответ на: комментарий от BooBoo

Приведенная задача вполне себе нормальная и не привязана к языкам.

Приведенная задача - это деструкция. В скале для деструкции есть специальные механизмы. Никто не будет деструкцию делать макрой.

То что ты на писал на Scala, типа «извлечём нужные ключи да и определим руками связывания»

То что я написал на скале работает вон в вышеприведенном примере, _для сколь угодно сложных структур_. Хочу видеть то же самое на лиспе.

И на скале можно сделать генерацию левой части assignment макрами. Просто это нахрен не надо - в скале никто так делать не будет.

r ★★★★★
()
Ответ на: комментарий от BooBoo

F# лучше чем ничего, да. Но опять же, больше мертво, чем живо.

По сравнению с лиспом? Серьезно?

r ★★★★★
()
Ответ на: комментарий от r

Я вас очень внимательно слушаю.

Ты это серьёзно? Ты, действительно, полагаешь что это не лохня?

(use-package :optima)
(use-package :optima.ppcre)

(defconstant +day+  "^(\\w+)\\s+(\\d{1,2})$")
(defconstant +date+ "^(\\d{2})/(\\d{2})/(\\d{4})$")
(defconstant +time+ "^(\\d{2}):(\\d{2}):(\\d{2})$")

(mapcan #'(lambda (a)
            (match a
              ((ppcre +day+  m d  ) (list (list m d  )))
              ((ppcre +date+ d m y) (list (list d m y)))
              ((ppcre +time+ h m s) (list (list h m s)))))
        (list "11/11/2013" nil "22:00:00" "January 3"))
; * (("11" "11" "2013") ("22" "00" "00") ("January" "3"))

BooBoo
()
Ответ на: комментарий от r

Ты не заметил слона. А именно ADT. Поинт был совсем не в регекспах.

Ну офигеть. Что тебе дал в данной задаче ADT, кроме долбёжки, вроде Some, Some, Some, Some... и беполезного вывода странного типа: List[Product with Serializable]?

BooBoo
()
Ответ на: комментарий от BooBoo

Да. Серьёзно. Особенно в связи с выходом Clojure. F# под шконкой. Просто смирись.

Они под одной шконкой.

r ★★★★★
()
Ответ на: комментарий от BooBoo

Что тебе дал в данной задаче ADT,


В данной задаче он подемонстрировал 4 вещи: exhaustiveness check, демонстрацию глубокой деконструкции в паттерн матчинге, полиморфизм по типам (сглаживание Option), и ленивую обработку. А ты показал регекспы.

r ★★★★★
()
Последнее исправление: r (всего исправлений: 3)
Ответ на: комментарий от BooBoo

Вот что-что. А это как раз таки статикопроблемы.

ADT - это не статикопроблемы. В динамическом эрланге они есть таки кое какие возможности глубокой деконструкции.

r ★★★★★
()
Ответ на: комментарий от r

exhaustiveness check

К статике не относится. Не указал общий шаблон — получил warning. Если общего шаблона нет и ничего не сматчилось — nil. Если нужно сигнализировать ошибку, когда ничего не сматчилось — ematch.

демонстрацию глубокой деконструкции в паттерн матчинге

К статике не относится. https://github.com/m2ym/optima — глубоко деконструируй, извлекай, матч и дорабатывай pattern matching как угодно под свои нужды. Всё что душе угодно. Всё писано на макросах. МП и макросы значительно более общая технология, чем захардкоженный сколь угодно крутой pattern-matching. Никакой «илитарности» и «свежести» в Scala в этом смысле нет.

полиморфизм по типам (сглаживание Option)

Статикопроблемы. В Lisp'е списки гетерогенные.

ленивую обработку

Никакого отношения к статике и ATD не имеет.

BooBoo
()
Ответ на: комментарий от r

Приведенная задача - это деструкция. В скале для деструкции есть специальные механизмы. Никто не будет деструкцию делать макрой.

Иключительно по той простой причине, что макросы в скале, вероятно, лоховские. «специальные механизмы» для деструктуризации захардкоженные непосредственно в язык совершенно не нужны (не плохо бы иметь максимум на уровне стандартной библиотеки), ибо практически тривиально реализуются макросами. Что можно наблюдать на примере optima.

BooBoo
()
Ответ на: комментарий от BooBoo

Ну коль уж на C++. А то фиг знает там в топе чего, может там на сишке всё писано, а собрано плюсовым компилятором :)

Ну, как бы, cstdio это часть плюсового стандарта. В данном случае вход достоверно валидный, простой, процесс однопоточный — зачем iostreams, которые делают много лишних вещей, когда достаточно cstdio, аналогично — зачем string, если достаточно char* и зачем не POD, если достаточно их. Короче, с iostreams, если их не насиловать (а так весь профит теряется), у меня получается совсем медленно :) Без них:

#include <cstdio>
#include <cstdlib>

#include <set>
#include <map>

template <class StackShape>
class ModelIface {

protected:

    typedef StackShape Stack;

    Stack stack;
    size_t hetero; // padding
    size_t size, homos;

    inline const char* show_state() const {
        return hetero ? homos ? "both" : "hetero" : homos ? "homo" : "neither";
    }

    ModelIface() : hetero(false), size(0), homos(0) {}

};

typedef std::multiset<int> SetShape;

typedef std::map<int, size_t> MapShape;

template <typename StackShape = MapShape>
struct Model {};

template <>
struct Model<SetShape> : public ModelIface<SetShape> {

    inline const char* ins(const int x) {
        stack.insert(x);
        if (stack.count(x) == 1) { if (++size > 1) hetero = true; }
        else ++homos;
        return show_state();
    }

    inline const char* del(const int x) {
        const Stack::iterator it = stack.find(x);
        if (it != stack.end()) {
            stack.erase(it);
            if (stack.count(x) == 0) { if (--size <= 1) hetero = false; }
            else --homos;
        }
        return show_state();
    }

};

template <>
struct Model<MapShape> : public ModelIface<MapShape> {

    inline const char* ins(const int x) {
        const std::pair<Stack::iterator, bool> ret = stack.insert(std::pair<int, size_t>(x, 0));
        if (ret.second) {
            if (++size > 1) hetero = true;
        } else {
            ++(ret.first->second);
            ++homos;
        }
        return show_state();
    }

    inline const char* del(const int x) {
        const Stack::iterator it = stack.find(x);
        if (it != stack.end()) {
            if (it->second > 0) {
                --(it->second);
                --homos;
            } else {
                stack.erase(it);
                if (--size <= 1) hetero = false;
            }
        }
        return show_state();
    }

};

int main()
{
    Model<> m;

    char buf[20];
    fgets(buf, 20, stdin);
    int n = atoi(buf), i;
    do {
        fgets(buf, 20, stdin);
        i = atoi(&buf[7]);
        puts(buf[0] == 'i' ? m.ins(i) : m.del(i));
    } while (--n);
}

На их тесте MapShape и SetShape не отличаются — ~1sec / ~5MB, у меня:

MapShape:

./homo-gen-in 10000000 10 | \time ./homo > /dev/null
1.43user 0.01system 0:02.44elapsed 59%CPU (0avgtext+0avgdata 4208maxresident)k
0inputs+0outputs (0major+323minor)pagefaults 0swaps
./homo-gen-in 10000000 1000 | \time ./homo > /dev/null
2.24user 0.01system 0:02.43elapsed 93%CPU (0avgtext+0avgdata 4448maxresident)k
0inputs+0outputs (0major+338minor)pagefaults 0swaps
./homo-gen-in 10000000 1000000 | \time ./homo > /dev/null
10.78user 0.14system 0:11.04elapsed 98%CPU (0avgtext+0avgdata 191872maxresident)k
0inputs+0outputs (0major+12052minor)pagefaults 0swaps
./homo-gen-in 10000000 1000000000 | \time ./homo > /dev/null
14.33user 0.36system 0:14.93elapsed 98%CPU (0avgtext+0avgdata 1248064maxresident)k
0inputs+0outputs (0major+78064minor)pagefaults 0swaps

SetShape:

./homo-gen-in 10000000 10 | \time ./homo > /dev/null 
98.31user 0.10system 1:38.90elapsed 99%CPU (0avgtext+0avgdata 5904maxresident)k
0inputs+0outputs (0major+429minor)pagefaults 0swaps
./homo-gen-in 10000000 1000 | \time ./homo > /dev/null
36.08user 0.22system 0:36.55elapsed 99%CPU (0avgtext+0avgdata 18976maxresident)k
0inputs+0outputs (0major+1246minor)pagefaults 0swaps
./homo-gen-in 10000000 1000000 | \time ./homo > /dev/null
16.64user 0.22system 0:16.99elapsed 99%CPU (0avgtext+0avgdata 389072maxresident)k
0inputs+0outputs (0major+24377minor)pagefaults 0swaps
./homo-gen-in 10000000 1000000000 | \time ./homo > /dev/null
15.55user 0.32system 0:16.01elapsed 99%CPU (0avgtext+0avgdata 939200maxresident)k
0inputs+0outputs (0major+58760minor)pagefaults 0swaps

то есть SetShape дегенеративен на малом разбросе.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

Короче, с iostreams, если их не насиловать (а так весь профит теряется), у меня получается совсем медленно :)

В том то и дело. С iostream'ом вообще вряд ли получится пройти на spoj. Ты кстати, на spoj запостил? Сколько получилось по времени?

Моя реализация такая:

(defparameter *ht*           (make-hash-table))
(defparameter *homo-counter* 0)
(defparameter *is-homo*      nil)
(defparameter *is-hetero*    nil)

(defun -insert (n)
  (let ((count (gethash n *ht*)))
    (if count
        (progn
          (incf (gethash n *ht*))
          (setf *is-homo* t)
          (incf *homo-counter*))
        (setf (gethash n *ht*) 1)))
  (when (> (hash-table-count *ht*) 1)
    (setf *is-hetero* t)))

(defun -delete (n)
  (let ((count (gethash n *ht*)))
    (when count
      (if (= count 1)
          (remhash n *ht*)
          (progn
            (decf (gethash n *ht*))
            (decf *homo-counter*)))
      (when (= *homo-counter* 0)
        (setf *is-homo* nil))
      (when (< (hash-table-count *ht*) 2)
        (setf *is-hetero* nil)))))

(defun -status ()
  (cond
    ((and *is-homo* *is-hetero*) "both")
    (     *is-homo*              "homo")
    (               *is-hetero*  "hetero")
    (t                           "neither")))

(defun homo ()
  (loop
     :repeat (read)
     :for line = (read-line)
     :for op   = (elt line 0)
     :for n    = (parse-integer line :start 7)
     :do
     (if (char= #\i op)
         (-insert n)
         (-delete n))
     (write-line (-status))))

(let ((*standard-input*  (sb-sys:make-fd-stream 0 :input  t :buffering :full))
      (*standard-output* (sb-sys:make-fd-stream 1 :output t :buffering :full)))
  (homo)
  (finish-output))

BooBoo
()
Ответ на: комментарий от r

А ты показал регекспы.

Нет, я тебе показал частичку optima, которая чуть более чем полностью состоит из макросов, с матичингом по рац. выражениям. А ты и не понял. Если у тебя есть какие-то более сложные примеры деструктуризации, то давай приводи. Мы и посмотрим кто там с чем не справится.

BooBoo
()
Ответ на: комментарий от BooBoo

К статике не относится

Серьезно? Покажи мне лисп:)

Не указал общий шаблон — получил warning.

Там нет общего шаблона. Варнинг там на отсутствующий настоящий вариант.

Всё что душе угодно.

Я уже когда-то сказл - лисп это такой IL. ДА - дорабатывай все что душе угодно. Но базовый набор очень скуден. В результате имеем то что имеем.

Статикопроблемы.

Статикорешение. В динамике не решается вообще без введения дискриминатора - рантаймтипа для бедных.

Никакого отношения к статике и ATD не имеет.

А никто и не говорит что имеет. А что к динамике имеет отношение dict-bind? Ты нафигачил лиспомакросов чтобы показать преймущества лиспа. Это наш ответ парижу. Вон покажи решение аналогичное вот этому скальному и как оно будет выглядеть. И не забудь что я тут ничего кроме стандартной либы не применял, а задачка эта относится к разряду повседневных - распознать некий вход.

r ★★★★★
()
Ответ на: комментарий от BooBoo

Иключительно по той простой причине, что макросы в скале, вероятно, лоховские.

Нет исключительно по той простой причине для этого есть спрециальные более удобные маханизмы.

специальные механизмы» для деструктуризации захардкоженные непосредственно в язык совершенно не нужны

Ну да ADT не нужны. Я посмотрю именно поэтому там есть всякие частные случаи вроде dict-bind. Это конечно нелоховство изобретать каждый раз свои собственныё честные случаи алгебраических типов.

ибо практически тривиально реализуются макросами.

Именно поэтому этого нет в стандартной библиотеке чтобы каждый на коленке не писал?

Что можно наблюдать на примере optima.

Пример оптимы показывает как раз хреновость стандартной библиотеки лиспа. Потому что в случае скалы указанный подход эот не фишечка - там все так реализовано и используется в стандартной либе. А в случае оптимы - это примочка написанная лично кем-то. То есть непринятый в лиспе подход. О чем я и говорю.

r ★★★★★
()
Ответ на: комментарий от BooBoo

С iostream'ом вообще вряд ли получится пройти на spoj.

Оно делается accepted, но уже не в топе, а в ... bottom, короче :) Неохота даже смотреть в чём там дело.

Ты кстати, на spoj запостил? Сколько получилось по времени?

13 место — ~1sec / ~5MB. Там много таких решений — наверно все пишут одно и то же тупо на std::map/std::multiset.

Моя реализация такая

(let ((*standard-input*  (sb-sys:make-fd-stream 0 :input  t :buffering :full))
      (*standard-output* (sb-sys:make-fd-stream 1 :output t :buffering :full))
      (*trace-output* *error-output*))
  (time (homo))
  (finish-output))
➜  spoj  ./homo-gen-in 10 10 | \time sbcl --noinform --noprint --disable-debugger --load "homo.lisp" > /dev/null
Evaluation took:
  0.000 seconds of real time
  0.000000 seconds of total run time (0.000000 user, 0.000000 system)
  100.00% CPU
  109,052 processor cycles
  0 bytes consed
  
0.26user 0.02system 0:00.29elapsed 97%CPU (0avgtext+0avgdata 207584maxresident)k
0inputs+0outputs (0major+6395minor)pagefaults 0swaps
➜  spoj  ./homo-gen-in 10000000 10 | \time sbcl --noinform --noprint --disable-debugger --load "homo.lisp" > /dev/null
Evaluation took:
  10.413 seconds of real time
  10.317433 seconds of total run time (10.200450 user, 0.116983 system)
  [ Run times consist of 0.192 seconds GC time, and 10.126 seconds non-GC time. ]
  99.08% CPU
  20,779,739,936 processor cycles
  3,519,986,224 bytes consed
  
10.46user 0.13system 0:10.70elapsed 99%CPU (0avgtext+0avgdata 347872maxresident)k
0inputs+0outputs (0major+10167minor)pagefaults 0swaps
➜  spoj  ./homo-gen-in 10000000 1000 | \time sbcl --noinform --noprint --disable-debugger --load "homo.lisp" > /dev/null
Evaluation took:
  12.103 seconds of real time
  11.902190 seconds of total run time (11.780209 user, 0.121981 system)
  [ Run times consist of 0.193 seconds GC time, and 11.710 seconds non-GC time. ]
  98.34% CPU
  24,151,750,796 processor cycles
  3,520,072,880 bytes consed
  
12.03user 0.14system 0:12.38elapsed 98%CPU (0avgtext+0avgdata 347984maxresident)k
0inputs+0outputs (0major+10670minor)pagefaults 0swaps
➜  spoj  ./homo-gen-in 10000000 1000000 | \time sbcl --noinform --noprint --disable-debugger --load "homo.lisp" > /dev/null
Evaluation took:
  16.913 seconds of real time
  16.648468 seconds of total run time (16.396507 user, 0.251961 system)
  [ Run times consist of 0.746 seconds GC time, and 15.903 seconds non-GC time. ]
  98.43% CPU
  33,749,201,068 processor cycles
  3,603,868,336 bytes consed
  
16.65user 0.27system 0:17.19elapsed 98%CPU (0avgtext+0avgdata 584656maxresident)k
0inputs+0outputs (0major+17579minor)pagefaults 0swaps
➜  spoj  ./homo-gen-in 10000000 1000000000 | \time sbcl --noinform --noprint --disable-debugger --load "homo.lisp" > /dev/null
Evaluation took:
  20.056 seconds of real time
  19.882977 seconds of total run time (18.828138 user, 1.054839 system)
  [ Run times consist of 2.491 seconds GC time, and 17.392 seconds non-GC time. ]
  99.14% CPU
  40,022,605,012 processor cycles
  4,191,032,800 bytes consed
  
19.09user 1.07system 0:20.34elapsed 99%CPU (0avgtext+0avgdata 2480352maxresident)k
0inputs+16outputs (0major+25761minor)pagefaults 0swaps

Так что запуск и измерение внешним time погоды не делает.

Не сильно хуже при большом разбросе (тогда оно вероятностно чаще hetero), но хуже при малом — я подозреваю, что у них там особый тест с малым разбросом (так что оно не всегда hetero). Ну и памяти больше.

Можешь попробовать продекларировать везде типы и declaim optimize/inline, ещё у тебя в -insert/-delete таблица вольно дёргается — у меня в случае MapShape ins за один проход доставляет итератор insert-ом и дальше всё константно, del — тоже за один проход доставляет find-ом итератор, _на котором_ (it) потом может быть выполнен erase — остальное константно.

quasimoto ★★★★
()
Последнее исправление: quasimoto (всего исправлений: 1)
Ответ на: комментарий от BooBoo

Нет. Ты просто не в курсе.

Еще как вкурсе. Сколько предложений о работе на лиспе существует в наших бараках?

r ★★★★★
()
Ответ на: комментарий от BooBoo

Если у тебя есть какие-то более сложные примеры деструктуризации, то давай приводи

Ты пока даже этот не реализовал. Там показаны 4 свойства скалы. exhaustiveness check мы уже сказали пока. Покажи пример с ADT такой же глубины, ленивостью и полиморфным flatten.

r ★★★★★
()
Ответ на: комментарий от r

Серьезно? Покажи мне лисп:)

Я уже показал, но ты в упор не видишь.

Там нет общего шаблона. Варнинг там на отсутствующий настоящий вариант.

Да в целом хрен с ним с этим warning'ом. На фиг он нужен-то? Если нужно, чтобы всё матчилось — добавь общий шаблон. Нужно сигнализировать ошибку, если не сопоставилось — ematch. Терять преимущества динамики ради сомнительного и бесполезного warning'а — вот радость.

Я уже когда-то сказл - лисп это такой IL.

Да. Ты частенько глупости говоришь. Вот и сейчас брякнул.

ДА - дорабатывай все что душе угодно. Но базовый набор очень скуден.

Не скуден, а минималистичен. Разница между скудностью и минимализмом огромна. В языке может быть сколь угодно много разных конструкций и финтифлюшек, но всегда найдется задача в которой все эти финтифлюшки будут бесполезны — т.е. понадобиться абстракция, которой нету в языке. И вот когда язык предоставляет инструмент для построения абстракций любой сложности, тогда финтифлюшку к задаче можно добавить. А вот когда не предоставляет — тогда «sosnooley». Lisp предоставляет такой инструмент. А Scala если и предоставляет, то, вероятно, весьма «скудный». Такие дела.

А что к динамике имеет отношение dict-bind?

Нет, не имеет. Но реализация имеет отношение к Lisp.

Вон покажи решение аналогичное вот этому скальному и как оно будет выглядеть.

Я уже показал, но ты это, видимо, видеть не хочешь. За исключением того, что в реализации на Scala есть бесполезный хлам, а в Lisp реализации — всё чётко и по делу.

И не забудь что я тут ничего кроме стандартной либы не применял, а задачка эта относится к разряду повседневных - распознать некий вход.

Ну и что. Какие-то пряги подключить распространённую либу? Вся разница лишь в том, что pattern matching в скалке захардкожен, а в CL — нет. И этот факт говорит не в пользу Scala.

BooBoo
()
Ответ на: комментарий от r

Нет исключительно по той простой причине для этого есть спрециальные более удобные маханизмы.

Покажи-ка как с помощью «специальных более удобных механизмов Scala» сопоставить значения по ключам. А то, я смотрю, ты ловко перевёл разговор с деструктуризации словаря на сопоставление рац. выражениям.

Ну да ADT не нужны. Я посмотрю именно поэтому там есть всякие частные случаи вроде dict-bind. Это конечно нелоховство изобретать каждый раз свои собственныё честные случаи алгебраических типов.

Да ну. С каких это пор словарь стал алгебраическим типом? Что ты несёшь? Также dict-bind важен не как самостоятельная фича, а как демонстрация МП Lisp. Но ты даже с таким примитивизмом не справился. О каких серьёзных вещах на скаламакросах может идти речь?

Именно поэтому этого нет в стандартной библиотеке чтобы каждый на коленке не писал?

Это смотря о каком Lisp'е речь. Если о Clojure, то деструктуризация словарей в коробке. Если о CL, то нет, ибо библиотека старовата. Но это очень маленькая проблема конкретно для CL. Ввиду макросов. Но фишка не в этом, а том, что я могу на CL такие вещи на коленке написать, а ты, на Scala, — нет :) Довольствуешься тем, что тебе подали. А я могу и то что есть взять, и то чего нет сделать.

Пример оптимы показывает как раз хреновость стандартной библиотеки лиспа.

Не умный ты человек. Пример optima показывает, что такая вещь как pattern matching любой сложности легко реализуется средствами МП самого языка и, следовательно, не нуждается в захардкоженности.

Потому что в случае скалы указанный подход эот не фишечка - там все так реализовано и используется в стандартной либе.

Это не стандартная либа — это захардкоженная часть языка Scala. А как в Scala реализована деструктуризация хеш-таблиц? :)

А в случае оптимы - это примочка написанная лично кем-то. То есть непринятый в лиспе подход.

Потрясающая логика!

О чем я и говорю.

Понятно :)

BooBoo
()
Ответ на: комментарий от r

Покажи пример с ADT такой же глубины, ленивостью и полиморфным flatten.

Ленивость к деструктуризации и матчингу не относится. И в приведенной тобой задачи совершенно никакого толку в ленивости. И зачем мне сраный flatten? Чем не устраивает mapcan (mapcar+nconc)?

Резюмирую:

List(Some("11/11/2013"), None, Some("22:00:00"), Some("January 3")) ->
List((11,11,2013), (22,00,00), (January,3))

("11/11/2013" nil "22:00:00" "January 3")) ->
(("11" "11" "2013") ("22" "00" "00") ("January" "3")).

Какие тут могут быть вопросы?

BooBoo
()
Ответ на: комментарий от BooBoo

Я уже показал, но ты в упор не видишь.

exhaustive check? где?

На фиг он нужен-то?

Ну да - нафиг они нужны - тулзы которые помогают. Настоящему хардкорному программисту помощь не нужна - он пишет без ошибок, а когда меняет - весь мир реагирует на его изменения изменяясь самостоятельно.

Если нужно, чтобы всё матчилось — добавь общий шаблон.

Мне нужно чтобы он указал где я мог ошибиться. А не забить все ошибки непонятно чем.

Терять преимущества динамики

Ну давай еще ты попробуй. Пока все преймущества что я слышу - «она позволяет писать неработающие программы».

Да. Ты частенько глупости говоришь. Вот и сейчас брякнул.

Пока только это ты и демонстрируешь. Ты не показываешь где сделано хорошо - ты показываешь «если можно то можно написать». Потенциальные возможности такие потенциальные.

Не скуден, а минималистичен.

Ну да ну да.

Разница между скудностью и минимализмом огромна

Никакой. Спроси любого любителя RoR.

В языке может быть сколь угодно много разных конструкций и финтифлюшек, но всегда найдется задача в которой все эти финтифлюшки будут бесполезны

Слово 'типовые' о чем тебе говорят? А я забыл - каждому кто пишет на лиспе попадается задача подобную которой никто и никогда не писал для него. Лисп это не система чтобы решать определенный класс задач - это слишком легко, лисп для хардкорных пацанов которым повезло писать все первый раз. Или они думают что пишут все первый раз. Я понимаю паттерн матчинг с глубокой деконструкцией изобрел тот пацан что написал оптиму. Все остальные хаскели содрали у него.

Нет, не имеет. Но реализация имеет отношение к Lisp.

Тогда какие претензии?

Я уже показал, но ты это, видимо, видеть не хочешь

Ты не показал. Там нет ни ленивости, ни глубокой деконструкции ни полиморфного flatten.

За исключением того, что в реализации на Scala есть бесполезный хлам

Ну вот мы и дошли до «мне не надо», «не скудно а минимализм» и прочие мантры и игра словами ничего общего с раельностью не имеющими. Потому лисп вот там и находится - если реальность не подтверждает теори - тем хуже для реальности. Если бы не было кложуры (которая как раз и жива за счет нефига не менималистичной жаба платформы под ней) - вообще бы остался только в лабах.

Какие-то пряги подключить распространённую либу?

Никаких. Подключай. Где решение?

Вся разница лишь в том, что pattern matching в скалке захардкожен

Что там захардкожено?

И этот факт говорит не в пользу Scala.

Это утверждение говорит о том что ты в лучшем случае не понял что там написано.

r ★★★★★
()
Ответ на: комментарий от BooBoo

Покажи-ка как с помощью «специальных более удобных механизмов Scala» сопоставить значения по ключам.

Что такое «сопоставить значения по ключам»? Сравнить две мапы? ==

С каких это пор словарь стал алгебраическим типом?

У раскрой тему почему словарь не может быть алгебраическим типом.

Также dict-bind важен не как самостоятельная фича, а как демонстрация МП Lisp.

То что она решается в лиспе макрой не говорит о том что она везде должна решаться макрой.

Но ты даже с таким примитивизмом не справился.

Потому что в скале это делают не так. Как мне в лиспе использовать language integrated xml? Никак? Гавно ваш лисп. Вот в скале и даже в жабаскрипте можно.

О каких серьёзных вещах на скаламакросах может идти речь?

О любых которые и там и там решатся макрами. А пока не покажешь как писать внутри лиспа на XML будем считать что даже жабаскрипт лучше.

Если о Clojure, то деструктуризация словарей в коробке

Если clojure то там JRE в коробке. Написанный на статической жабе.

Если о CL, то нет, ибо библиотека старовата.

Таневже? А я думал минималистична.

Но фишка не в этом, а том, что я могу на CL такие вещи на коленке написать, а ты, на Scala, — нет :)

В скале на коленке это писать не надо - это есть в стандартной либе. Тебе что не нравится что все уже написано до нас?

Довольствуешься тем, что тебе подали.

Ты пока не показал что мне не хватит в скале что мне в скале нужно, а не тебе в лиспе.

Пример optima показывает, что такая вещь как pattern matching любой сложности легко реализуется средствами МП самого языка

Пример показывает что в стандартной либе нет даже алгебраических типов с глубокой доконсрукцией. Что моногое говорит о стандартной либе.

Это не стандартная либа — это захардкоженная часть языка Scala.

Читай по буквам _там нет ничего захардкоженого_. Это _либа_.

А как в Scala реализована деструктуризация хеш-таблиц? :)

Начнем с того что такое использование хештаблиц - это вообще что-то из разряда ООП на хэшах в перле.

Потрясающая логика!

А что - ты мне покажешь стандартную либу использующую оптиму?

r ★★★★★
()
Ответ на: комментарий от BooBoo

Ленивость к деструктуризации и матчингу не относится.

И что?

. И в приведенной тобой задачи совершенно никакого толку в ленивости.

Вообще-то я привел не задачу а демонстрацию 4х свойств и попросил продемонстрировать аналогичные. И второе даже в приведенном примере с нее толк есть - как думаешь зачем там slice? И что будет если промапить этот список на втором элементе?

r ★★★★★
()
Ответ на: комментарий от r

Какого именно ООП тебе не хватает в хаскеле?

Там нет никакого.

ocaml - труп с сомнительным императивным генотипом, посмотри на циклы.

F#.

.net это то о чем я всегда мечтал, ага.

это ты мне на фоне рубиевских @собак, def end, do end, begin rescue else end, class end рассказываешь?

При чем тут руби вообще? Посмотри хотя бы на питон.

Какой ужос. Решетка вместо точки. Разрыв шаблона. К названию может еще претензии есть?

Просто это неудачный синтаксис, никаких особых ужасов.

Спасибо - смешно.

По втором ссылке тоже смешно?

+GIL.

Нету там никакого gil.

Ok, и никакого smp, параллелизма тоже нет. Круто.

alienclaster ★★★
()
Ответ на: комментарий от r

Вот ты и сам признал, что макры в скале неюзбельны.

Ты с дубу рухнул?

Нет. Если инструментом не принято пользоваться в какой-то среде, языке - значит оно неудобное.

Макры в скале писались чтобы решать задачи, а не чтобы перетягивать из лиспа то что в скале нахрен не впилось.

При чем тут лисп. Макры это о добавлении синтаксиса и кодогенерации. В засахаренно обфусцированном синтаксесе скалы это звездец.

Может назовем скалу неюзабельной потому что там CLOSа лисповского нету?

Если его можно органично добавить - то не назовем. Не везде CLOS уместен.

alienclaster ★★★
()
Ответ на: комментарий от r

Сколько предложений о работе на лиспе существует в наших бараках?

Ты недавно отвечал какому-то анонимному аналитику на подобный вопрос о скале, вспомни что ты ответил и рефлексани.

alienclaster ★★★
()
Ответ на: комментарий от alienclaster

Там нет никакого.

Что тебе _конкретно_ не хватает в хаскеле с точки зрения ООП?

.net это то о чем я всегда мечтал, ага.

К пуговицам претензии есть?

При чем тут руби вообще? Посмотри хотя бы на питон.

....pass

Просто это неудачный синтаксис, никаких особых ужасов.

По сравнению с?

По втором ссылке тоже смешно?

Именно по второй в основном и смешно.

Ok, и никакого smp, параллелизма тоже нет. Круто.

Юзай F#.

r ★★★★★
()
Последнее исправление: r (всего исправлений: 1)
Ответ на: комментарий от alienclaster

Ты недавно отвечал какому-то анонимному аналитику на подобный вопрос о скале,

Что скальных предложений завались. Кто-то может предъявить лисповые?

r ★★★★★
()
Ответ на: комментарий от alienclaster

Нет. Если инструментом не принято пользоваться в какой-то среде, языке - значит оно неудобное.

Им принято пользоваться. Им не принято пользоваться для того для чего им пользоваться совсем не надо ввиду более удобных инструментов.

Макры это о добавлении синтаксиса и кодогенерации.

Правильно. Какой макрой в лиспе добавляются funcall?

r ★★★★★
()
Ответ на: комментарий от r

Что тебе _конкретно_ не хватает в хаскеле с точки зрения ООП?

Мутируемых структур, объектов, переменных.

.net это то о чем я всегда мечтал, ага.

К пуговицам претензии есть?

Отсутствие тех же макросов это о пуговицах?

При чем тут руби вообще? Посмотри хотя бы на питон.

....pass

У тебя обычно много выражений делающих «ничего» по коду разбросано? Крутой пример, чо.

Просто это неудачный синтаксис, никаких особых ужасов.

По сравнению с?

С той точкой же.

По втором ссылке тоже смешно?

Именно по второй в основном и смешно.

По _другой_, если так понятнее.

Ok, и никакого smp, параллелизма тоже нет. Круто.

Юзай F#.

Зачем, если там даже макросов нет и быть не может (нормальных)?

alienclaster ★★★
()
Ответ на: комментарий от r

Ты недавно отвечал какому-то анонимному аналитику на подобный вопрос о скале,

Что скальных предложений завались.

По сравнению с жабой их ноль. Суть заключалась в том, что ты говорил, мол, разрабов хантят, и вакансии - хреновый показатель востребованности.

Кто-то может предъявить лисповые?

Конечно. В Украине grammarly на слуху, поисковик для вьетнама в России. На интересную работу не ищут «программисто на $whatever», а хантят специалистов в каких-то конкретных областях - лингвистика и natural language processing, search engines и data mining, матану^W..., просто ищут сообразительных и учат. Добро пожаловать в 2013-й год.

alienclaster ★★★
()
Ответ на: комментарий от r

Им принято пользоваться. Им не принято пользоваться для того для чего им пользоваться совсем не надо ввиду более удобных инструментов.

Какие есть особые уличные инструменты для кодогенерации в скале, которых нет в лиспе?

Макры это о добавлении синтаксиса и кодогенерации.

Правильно. Какой макрой в лиспе добавляются funcall?

funcall - это костыль lisp-2, зачем, спрашивается, его делать макрой, если все, что ожидает получить funcall и использовать его - ждет функцию? Мы тут обсуждаем ущербность CL или неудобство синтаксиса для макр?

alienclaster ★★★
()
Ответ на: комментарий от x4DA

проблема funcall в том, что он вообще есть ;)

Да всё круто же. За символом может быть закреплена как функция, так и переменная. Удобно же. В Ruby также сделано. Это фишка дизайна.

BooBoo
()
Ответ на: комментарий от BooBoo

Чем удобно? Разве что имена для переменных проще выдумывать ;)

То что в руби так сделано - ну как бы не особо показатель

x4DA ★★★★★
()
Ответ на: комментарий от x4DA

Старая тема? Lisp-1 vs. Lisp-2? Так ведь было уже много раз. Даже в The Evolution of Lisp немного затронули, если не изменяет склероз.

dave ★★★★★
()
Ответ на: комментарий от alienclaster

Мутируемых структур, объектов, переменных.

Это какое-то новое слово в ООП.

Отсутствие тех же макросов это о пуговицах?

Нет - ты просил язык - тебе дали язык. А теперь у тебя претензии к чему к платформе? Можно уже тогда весь список услышать - может у тебя и на фазу луны ограничения будут.

У тебя обычно много выражений делающих «ничего» по коду разбросано? Крутой пример, чо.

Это просто пример. В окамле тебя почему-то отсутсвие поддержки SMP беспокоит, а питоновский GIL не жмет когда ты его в пример приводишь или рубиевый global VM lock?

Зачем, если там даже макросов нет и быть не может (нормальных)?

Питон который ты привел в пример полон макросами?

r ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.