juan_gandhi: (Default)
Juan-Carlos Gandhi ([personal profile] juan_gandhi) wrote2008-03-06 06:04 pm

some lambda in plain java

See what people, I mean, [livejournal.com profile] dtm, can do with our Java::

  // Look, it's an anonymous recursive function!
  public void testY() {
    assertEquals(720,
        new Function<Function<Fii, Fii>, Fii>() {
          public Fii apply(final Function<Fii, Fii> f) {
            return new Branch() {
              public Fii apply(final Branch x) {
                return f.apply(new Fii() {
                  public Integer apply(Integer y) {
                    return x.apply(x).apply(y);
                  }
                });
              }
            }.apply(new Branch() {
              public Fii apply(final Branch x) {
                return f.apply(new Fii() {
                  public Integer apply(Integer y) {
                    return x.apply(x).apply(y);
                  }
                });
              }
            });
          }
        }.apply(new Function<Fii, Fii>() {
          public Fii apply(final Fii f) {
            return new Fii() {
              public Integer apply(Integer i) {
                return (i <= 0) ? 1 : i * f.apply(i - 1);
              }
            };
          }
        }).apply(6).intValue());
  }
}

[identity profile] ygam.livejournal.com 2008-03-07 02:19 am (UTC)(link)
He is using F-bounded polymorphism to implement recursion.

[identity profile] ivan-gandhi.livejournal.com 2008-03-07 05:42 am (UTC)(link)
1. You are right.
2. How do you know.
3. What kind of bastard interviewed you at Google?
4. Do you think lowly code monkeys like me can ever be entitled to be hired by your company?

[identity profile] ygam.livejournal.com 2008-03-07 06:05 am (UTC)(link)
1. I know.

2. Kim Bruce (http://ygam.livejournal.com/128302.html)?

3. A namesake of a former governor of California.

4. We have coding monkeys aplenty.

[identity profile] ivan-gandhi.livejournal.com 2008-03-07 06:35 am (UTC)(link)
Fuck! Shit! Они блин охренели, какого-то тупого чикагского н**ра из суппорта, но с msce, посылать интервьюировать приличных людей. Кадровики хреновы. Блин.

[identity profile] ygam.livejournal.com 2008-03-08 05:48 am (UTC)(link)
Я неправ; F-bounded polymorphism - это несколько иное. Но здесь действительно используется возможность определить класс, содержащий метод, принимающий параметр типа этого класса. Такой класс тоже можно рассматривать, как наименьшую фиксированную точку уравнения.

[identity profile] deni-ok.livejournal.com 2008-03-07 10:53 am (UTC)(link)
А, вот почему продвинутые джависты стали говорить о ко-(контр-)вариантности:
public interface Function<F,T>

T apply(F from)
Понятно :)

[identity profile] ivan-gandhi.livejournal.com 2008-03-07 04:25 pm (UTC)(link)
Конечно! ;)

[identity profile] faceted-jacinth.livejournal.com 2008-03-07 11:46 am (UTC)(link)
Wow!

Переписал (http://fj.technocore.ru/freestuff/TestYCombinator.cs) её на шарпе, чтобы разобраться. Правда, ввиду отсутствия анонимных классов пришлось юзать обычные, кушающие конструктором (анонимный) делегат -- что забавно, на мой вкус получилось красивее.

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


Правильно ли я понимаю, что словосочетание F-bounded polymorphism здесь означает просто то, что мы можем написать класс, у которого есть метод, берущий в качестве параметра экземпляр этого же класса? При том, что полиморфизма тут как такового нет вообще, я могу разъединить иерархию классов (проверил -- могу), полностью избавиться от генериков (влом проверять, но, кажется, могу) и всё продолжит работать?

[identity profile] faceted-jacinth.livejournal.com 2008-03-07 05:12 pm (UTC)(link)
А, нет, залез в электричку и тут же понял, что я нагнал, полиморфизм тут есть, он проявляется в том, что я могу присвоить в переменную указатель на любой метод соответствующей сигнатуры. Ну, или если бы я без делегатов писал, как-нибудь исхитрившись сделать лексические кложуры ручками, мне бы была необходима возможность передать в качестве экземпляра абстрактного класса
Branch
{
public abstract Fii Apply(Branch b);
}
произвольную имплементацию (в которой в Апплае как-то отражалась бы структура соответствующей лямбды.

Переписал (http://fj.technocore.ru/freestuff/TestYCombinator2.cs), кстати, на чистые делегаты, без классов. Если вдруг интересно.

Ключевая строчка, позволяющая устроить всё это безобразие:
public delegate Fii Branch(Branch p);

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

Получилось совсем ясно и чисто.

Удивляюсь, как вам удаётся прогать на жаве. Очень ведь должно было бы быть неприятное ощущение, что язык slightly inferior по сравнению с точно таким же, но другим, как бы ничего серьёзного, но каких-то мелочей не хватает, причём нет ни малейшей надежды, что разработчики смирят гордыню и их добавят.

[identity profile] ivan-gandhi.livejournal.com 2008-03-07 05:35 pm (UTC)(link)
О как красиво с делегатами!

Насчё же джавы - да, достаёт. Да, legacy language. Да, предпочитаю джаваскрипт. Да, перестал на джаве даже пробовать писать функционально.

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

[identity profile] just-developer.livejournal.com 2008-03-07 05:53 pm (UTC)(link)
Согласен.
Не стоит зря говорить именно на язык

[identity profile] just-developer.livejournal.com 2008-03-07 12:48 pm (UTC)(link)
I have following code in current project..
Who said that Java isn't declarative language?

        XTComplexType cpxReject = complexType("Reject",
            extension(
                complexType("OrderResponse",
                    sequence(
                        elementref("core-elements:orderRequestId"),
                        elementref("core-elements:orderRequestRefId").minOccurs0(),
                        elementref("core-elements:orderId").minOccurs0(),
                        elementref("core-elements:secondaryOrderId").minOccurs0(),
                        elementref("core-elements:clientOrderId").minOccurs0(),
                        elementref("core-elements:clientOrderLinkId").minOccurs0(),
                        elementref("core-elements:listId").minOccurs0(),
                        elementref("core-elements:secondaryListId").minOccurs0(),
                        elementref("core-elements:sendingTime").minOccurs0(),
                        elementref("core-elements:possibleResend").minOccurs0(),
                        elementref("core-elements:transactTime"),
                        element("party","core-components:Party").minOccurs0().maxOccursUnbounded(),
                        elementref("core-elements:processingInstruction").minOccurs0().maxOccursUnbounded()
                    ),
                    attribute("schemaVersion","SchemaVersion")
                ),
                sequence(
                    elementref("core-elements:orderStatus"),
                    elementref("core-elements:cfiCode").minOccurs0(),
                    elementref("core-elements:businessStream").minOccurs0(),
                    elementref("core-elements:symbol").minOccurs0(),
                    elementref("core-elements:securityId").minOccurs0(),
                    elementref("core-elements:alternateSecurityId").minOccurs0().maxOccursUnbounded(),
                    elementref("core-elements:securityExchange").minOccurs0(),
                    elementref("core-elements:securityCountry").minOccurs0(),
                    elementref("core-elements:exDestination").minOccurs0(),
                    elementref("core-elements:side").minOccurs0(),
                    elementref("core-elements:text").minOccurs0(),
                    element("rejectParty","core-components:Party").minOccurs0()   //TODO Add party component here
                )
            )
        );
        XTComplexType orderReplaceReject = complexType("OrderReplaceReject",
            extension(
                cpxReject,
                sequence(
                    elementref("core-elements:cancelRejectResponseTo"),
                    elementref("core-elements:requestRejectReason")
                )
            )
        );

[identity profile] ivan-gandhi.livejournal.com 2008-03-07 04:26 pm (UTC)(link)
Looks cool. And makes a lot of sense; will try to use this style... not everybody supports this, though.

[identity profile] just-developer.livejournal.com 2008-03-07 05:26 pm (UTC)(link)
Methods extension, complexType, sequence and etc. have declaration like this:
 
public static XTExtension extension(XTNode... nodes);

Than we use
import static xsdgraph.model.XTUtil.*;


Also C-strXXX like style for setting arbitrary number of attributes:

public class XTElement {
    public XTElement minOccurs(int value) {
        minOccurs = value;
        return this;
    }
}

[identity profile] mikkim08.livejournal.com 2008-03-07 05:41 pm (UTC)(link)
Последнeе вроде с легкой руки М. Фоулера называется fluent interface.

Я вот думаю такой стиль для манипуляции с коллекциями использовать. Типа, select( new Predicate() {...}).orderedBy(new Predicate() {...}).groupedBy(...). А то

[identity profile] just-developer.livejournal.com 2008-03-07 05:58 pm (UTC)(link)
идея не очень хорошая.
не будет оптимизации запроса.
В идеале - так строить запрос - а потом его прозрачно выполнять.
Вроде
select( new Predicate() {...}).orderedBy(new Predicate() {...}).groupedBy(...).go();

Есть пакет работы с матрицами с похожим подходом.

[identity profile] mikkim08.livejournal.com 2008-03-07 06:14 pm (UTC)(link)
Я так тоже думал. Только все эти "go()", "doit()", "execute()" и др. в коде задрали уже :)

Да и никакой оптимизации запросов я, если честно, не планировал. Просто хочется заменить все эти дурацкие циклы, имплементирующие подобную бизнес-логику (e.g. retrieve all purchased items along with their expiration date and group them by bundle id) на коллекциях, возвращаемых всякими веб-сервисами и прочими API, на что-то б.-м. читабельное. Ну и чтоб лепить эту логику быстрее.

Но, может, Вы и правы.

[identity profile] just-developer.livejournal.com 2008-03-07 06:00 pm (UTC)(link)
C- strXXX методы придумали несколько раньше...

[identity profile] mikkim08.livejournal.com 2008-03-07 06:15 pm (UTC)(link)
Зато Фоулер им придумал звучное название :)

[identity profile] mikkim08.livejournal.com 2008-03-07 05:11 pm (UTC)(link)
Вот Вы будете смеяться, а я каждый раз задумываясь о подобном, задаюсь вопросом, как заставить eclipse автоматически придерживаться подобной индентации.

[identity profile] mikkim08.livejournal.com 2008-03-07 05:13 pm (UTC)(link)
Хм. Хотя нет, с Вашим примером вроде все просто. А вот с исходным -- сложнее.

[identity profile] just-developer.livejournal.com 2008-03-07 05:50 pm (UTC)(link)
Да ладно - отступы это не самое главное в жизни ;)

[identity profile] mikkim08.livejournal.com 2008-03-07 05:58 pm (UTC)(link)
Да я и сам понимаю, что это все несерьезно. Но заедает все равно :)
nine_k: A stream of colors expanding from brain (Default)

[personal profile] nine_k 2008-03-07 07:57 pm (UTC)(link)
Hehe, I've got a plenty of very similar code in my Python project. Web services, ain't it? :)

But this is rather straightforward; an ORM would present a better case.