LINUX.ORG.RU

JVM-based языки. Кто умеет такой синтаксис?


0

1

Какие из JVM-based языков умеют смешивать стили массивов? Скажем, задать хэш в подобном виде:

hash = ['item1', 'item2' => 'subst1', 1234];

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

★★★★★

Охохонюшки. А зачем такое нужно не подскажете? Вообще если смотреть - то груви. Он щас самы поддерживаеимый, простой и вместе с тем фичастый язык для JVM.

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

А как у него с производительностью? Если типы указывать, то арифметика по скорость как жава будет или нет? Когда я последний раз смотрел, там все интерпретировалось всегда и жутко тормозило.

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

>А зачем такое нужно не подскажете?

Люблю компактный и наглядный синтаксис :)

Вообще если смотреть - то груви.


А пошустрее ничего нет? А то даже Quercus будет в разы быстрее...

Хотя посмотрю, как с ним дела сейчас стали. Год назад было ещё всё плохо :)

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

>там все интерпретировалось всегда и жутко тормозило.

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

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

>наглядный синтаксис :)

Хренасе наглядный - смешивать хешмапы и массивы =)

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

>А пошустрее ничего нет?

Groovy++ - там опциональная статическая типизация дает существенный прирост производительности.

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

>Хренасе наглядный - смешивать хешмапы и массивы =)

Код-обработчик такой записи пишется один раз. А вот сами записи такого вида у меня используются часто. И дико бесит, если нужно писать ['item1': 'item1']

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

Что-то, у меня не получается задать подобный формат. Запись вида collection = [«x», «y», «z» : «t»] вызывает ошибку компиляции.

А офсайт Groovy сейчас висит.

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

>Люблю компактный и наглядный синтаксис :)
>А пошустрее ничего нет?

Если не-JVM-based то, то в Euphoria элементы массива могут быть динамической смесью различных типов: ряды (sequence), гибкие массивы, ...

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

Самый фичастый, ломающий груви об колено - это Scala

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

Сначала надо понять как по-английски называется то, что хочет ОП. Потом погуглить это. Я ничего пока не нагуглил

Karapuz ★★★★★ ()

судя по всему это какая-то фича из PHP, как называется?

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

>ломающий груви об колено - это Scala

Смотря в чем. Скала скоро просто лопнет от синтаксических конструкций. А груви - просто и умеренно фичаст.

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

> collection = [«x», «y», «z» : «t»]

Можешь написать обработчик который будет разруливать конструкцию вида [«x», «y», {«z»:«t»}]. Почти также лаконично, без всяких извращений.

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

Скала скоро просто лопнет от синтаксических конструкций


Не лопнет. Ключевых слов в ней что-то 40, в C# >74, в Java чот-то около 50

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

>Ключевых слов в ней что-то 40

Меньше чем в джаве? ой не верю, ой не верю. Но в любом случаи я говорил о синтаксических конструкциях а не о кейвордах.

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

Знаю. Но хочется чего-то более вкусного и производительного :) Quercus, который в байткод компилит даже пощупать не дают, только за деньги...

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

Подобная запись принята в lua.

Погуглить реализацию lua на JVM? Хотя это как-то совсем.

vladimir-vg ★★ ()

я вообще не понимаю, *зачем* это может быть надо

так или иначе, взгляни на явовский enum (это не язык, это конструкция явы)

www_linux_org_ru ★★★★★ ()

groovy, scala. В крайнем случае можно написать миниDSL для такого хэша

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

>так или иначе, взгляни на явовский enum

Даже близко не то :)

я вообще не понимаю, *зачем* это может быть надо


Я выше описывал. Например, для описания привязок полей в БД к методам/свойствам объекта в ORM. Чтобы не было лишней писанины при совпадении имён, но при этом чтобы можно было задавать раздельные имена или, вообще, функции обработки если это нужно.

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

>scala

Хм. Интересно. Записи смешанного типа она принимает.
[code]
scala> («id», «title», «source» -> «message»);
res6: (java.lang.String, java.lang.String, (java.lang.String, java.lang.String)) = (id,title,(source,message))
[/code]

Правда, теперь нужно смотреть, как такое будет разбираться в анализаторе. Но интересно...

В крайнем случае можно написать миниDSL для такого хэша


А производительность? :)

В общем, экспериментов ещё много нужно будет, походу...

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

«source» -> «message»

Еще и так можно записать tuple? или я не понял

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

Люблю компактный и наглядный синтаксис :)

Надеюсь проект не опенсорсный, а то поиск помощников будет сложнее чем поиск партнера для лица нетрадиционной ориентации ;) чтоб любили «такой» синтаксис :)

I-Love-Microsoft ★★★★★ ()
Ответ на: комментарий от I-Love-Microsoft

>Надеюсь проект не опенсорсный, а то поиск помощников будет сложнее

Безусловно опенсорсный. Но как опенсорс связан с поиском помощников? :)

...

Предложи более удобный синтаксис для частного случая описания привязок полей ORM с избеганием дублирования записей? То есть я, конечно, понимаю, что Java-программерам семь копипаст - не дублирование, но нужно же и к хорошему привыкать :D

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

>scala

Хех. Да, походу, если в чём-то под JVM такое возможно, то только в Scala. Хотя навскидку пока задачу не решил, полученная смесь не итерируется по foreach, а если сразу задавать описание как список, то это лишнее ключевое слово. Но радует отчасти схожесть с разработчиками языка во взглядах на краткость описания:

1 to 10 foreach println

1
2
3
4
5
6
7
8
9
10

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

Хотя навскидку пока задачу не решил

Ну, например, так:

Map(List("a", "b" -> "c", "d") map {
     case tuple @ (_, _) => tuple        
     case s => s -> s                    
} : _*).asInstanceOf[Map[String, String]]

Разумеется, это можно вынести в функцию. Но всё равно решение невероятно далеко от изящества. Если бы мне кто-то дал такой код, то я бы задушил автора клавиатурным шнурком.

Более правильно это делать используя тип Either:

Map(List(Left("a"), Right("b" -> "c"), Left("d")) map {
     case Right(tuple) => tuple
     case Left(s) => s -> s
} : _*)

Но запись длиннее. В общем, я бы писал везде кортежами и не парился. Статическая типизация. Профит от неё превышает неудобства.

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

Можно ещё неявными преобразованиями поколдовать. Вполне себе изящное и краткое решение. Только надо иметь в виду, что это кратчайший путь докопаться до ада в Scala.

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

>Ну, например, так:

О! Понятно, куда плясать нужно.

...

Попутно присматриваюсь к фреймворкам Lift и Akka.

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

Делается это так:

implicit def string2tuple(s: String) = (s, s)

Map("a", "b" -> "c", "d")
Zenom ★★★ ()
Ответ на: комментарий от KRoN73

>О! Понятно, куда плясать нужно.

Не, я уже передумал туда плясять%)

Попутно присматриваюсь к фреймворкам Lift и Akka.

Lift мне пришёлся по нраву. С Akka работать пока не приходилось.

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

Меня ТС игнорит кажись, что он хочет сделать? Судя по твоему посту простое определение элемента - это тупл из того же самого элемента два раза. Так? Если да, то твое решение правильное и очевидное. Нужно просто завернуть в функцию и пользоваться

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

Чорд, гениально. И работает? Покажи код дальше как пользоваться? Извини что задалбываю, у меня сейчас Вин7Макс без компиляторов, не свой комп

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

>implicit def string2tuple(s: String) = (s, s)

Ага, понятно. А то вариант с Map() я попробовал, но без этой строки он не работал :)

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

>удя по твоему посту простое определение элемента - это тупл из того же самого элемента два раза. Так?

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

Покажи код дальше как пользоваться?

Собственно, это всё. Такая конструкция будет транслироваться в Map(string2tuple(«a»), «b» -> «c», string2tuple(«d»)). Попробовать можно на http://www.simplyscala.com/

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

Я еще зелен в Scala. А оно так все строчки в коде будет пытаться в тупл превратить? ))) Может еще рекурсивно? )))

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

Нет, магия включается только тогда, когда тип аргумента не совпадает с ожидаемым.

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

Тогда наверное лучше десять раз думать перед тем как это использовать. Можна таких имплиситов нахватать где угодно, что потом вообще ничего не захочется

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

Именно поэтому я про них не сразу вспомнил. Подсознательное неприятие средств, способных привести на тёмную сторону Силы.

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

> Предложи более удобный синтаксис для частного случая описания привязок полей ORM с избеганием дублирования записей?

(bind-orm-field (item1 item2) («subst1» 1234))

а дальше как макрос bind-orm-field реализуешь, так он и будет работать.

JVM-based

Clojure?

anonymous ()
(defstruct hash-reader-entry key value)

(defvar *brace-reader* nil)

(defun curly-brace-reader (s c)
  (declare (ignore c))
  (unless *brace-reader*
    (error "Curly brace context error"))
  (let* ((*brace-reader* nil)
         (entry (read-delimited-list #\} s t)))
    (assert (= 2 (length entry))
        () "Ill-formed hash entry: {~{~a~^, ~}}" entry)
    (make-hash-reader-entry
        :key (first entry) :value (second entry))))

(defun close-curly-brace-reader (s c)
  (declare (ignore s c))
  (error "Unmatched close curly brace"))

(defun brace-reader (s c)
  (declare (ignore c))
  (let* ((*brace-reader* t)
         (items (read-delimited-list #\] s t)))
    (let ((ht (gensym)))
      `(let ((,ht (make-hash-table :test #'equal)))
         ,@(mapcar (lambda (x)
                     (if (hash-reader-entry-p x)
                       `(setf (gethash ,(hash-reader-entry-key x) ,ht)
                              ,(hash-reader-entry-value x))
                       `(setf (gethash ,x ,ht) ,x)))
             items)
         ,ht))))

(defun close-brace-reader (s c)
  (declare (ignore s c))
  (error "Unmatched close brace"))

(defun sharp-brace-reader (s c n)
  (declare (ignore c n))
  (let ((form (read-delimited-list #\] s t)))
    (assert (= 2 (length form))
        () "Invalid hash access syntax: #[~{~a~^, ~}]" form)
    `(gethash ,(second form) ,(first form))))


(set-macro-character #\{ #'curly-brace-reader)
(set-macro-character #\} #'close-curly-brace-reader)
(set-macro-character #\[ #'brace-reader)
(set-macro-character #\] #'close-brace-reader)
(set-dispatch-macro-character #\# #\[ #'sharp-brace-reader)

(defmethod print-object ((object hash-table) stream)
  (princ "[ " stream)
  (maphash (lambda (k v)
             (if (equal k v)
               (format stream "~s " k)
               (format stream "{ ~s ~s } " k v)))
    object)
  (princ "]" stream))

;;пример:
;;   (defvar *hash* ["item1" {"item2" "subst1"} 1234])
;;=> *HASH*
;;   #[*hash* "item1"]
;;=> "item1"
;;   #[*hash* "item2"]
;;=> "subst1"
;;   #[*hash* 1234]
;;=> 1234
;;   (setf #[*hash* "item3"] 56789)
;;=> 56789
;;   (print *hash*)
;;=> [ "item1" { "item2" "subst1" } 1234 { "item3" 56789 } ]

Реализацию под JVM брать здесь: http://common-lisp.net/project/armedbear/

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

небольшой фикс, для предотвращения двойного вычисления

(defun brace-reader (s c)
  (declare (ignore c))
  (let* ((*brace-reader* t)
         (items (read-delimited-list #\] s t)))
    (let ((ht (gensym))
          (val (gensym)))
      `(let ((,ht (make-hash-table :test #'equal)))
         ,@(mapcar (lambda (x)
                     (if (hash-reader-entry-p x)
                       `(setf (gethash ,(hash-reader-entry-key x) ,ht)
                              ,(hash-reader-entry-value x))
                       `(let ((,val ,x))
                          (setf (gethash ,val ,ht) ,val))))
             items)
         ,ht))))

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