小编kor*_*rok的帖子

是什么让Java比C更容易解析?

我熟悉C和C++的语法是上下文相关的事实,特别是你需要在C中使用"lexer hack".另一方面,我的印象是你只能解析Java尽管两种语言之间存在相当大的相似性,但仍有2个前瞻性令牌.

你需要改变什么才能使它更易于解析?

我问,因为我所见过的关于C的上下文敏感性的所有例子在技术上都是允许的,但非常奇怪.例如,

foo (a);
Run Code Online (Sandbox Code Playgroud)

可以foo用参数调用void函数a.或者,它可以声明a是一个类型的对象foo,但你可以很容易地摆脱parantheses.在某种程度上,这种奇怪之处的发生是因为C语法的"直接声明者"生成规则实现了声明函数和变量的双重目的.

另一方面,Java语法具有用于变量声明和函数声明的单独生成规则.如果你写

foo a;
Run Code Online (Sandbox Code Playgroud)

然后你知道它是一个变量声明,foo可以毫不含糊地解析为一个类型名.如果foo尚未在当前作用域中的某处定义类,则这可能不是有效代码,但这是可以在稍后的编译器传递中执行的语义分析的工作.

我已经看到它说由于typedef很难解析C,但你也可以在Java中声明自己的类型.此外direct_declarator,哪种C语法规则有错?

c java grammar parsing

89
推荐指数
1
解决办法
5556
查看次数

Common Lisp中的别名包名称

我在Common Lisp中使用外部包进行项目; 我希望能够使用该软件包,但将其别名为一个较短的名称,类似于我可以做的Clojure

(require '[unnecessarily-long-package-name :as ulpn])
Run Code Online (Sandbox Code Playgroud)

为了避免命名冲突,我宁愿不这样做:

(defpackage #:my-package
  (:use #:cl #:other-package))

(in-package :my-package)

(take-over-world "pinky" "brain")
Run Code Online (Sandbox Code Playgroud)

在哪里other-package定义take-over-world.我每次都可以输入完整的合格包名称:

(defpackage #:my-package
  (:use #:cl))

(in-package :my-package)

(other-package:take-over-world "pinky" "brain")
Run Code Online (Sandbox Code Playgroud)

但在我的情况下,我导入的包有一个不必要的长名称.有没有办法可以other-package用作

(op:take-over-world "pinky" "brain")
Run Code Online (Sandbox Code Playgroud)

通过别名来op?在Practical Common Lisp的相关章节中,我无法找到类似的内容.

clojure common-lisp

11
推荐指数
2
解决办法
1069
查看次数

为什么在Clojure中`disj`和`dissoc`有不同的功能?

因为我见过到目前为止,Clojure的核心功能几乎都是针对不同类型的集合,例如工作conj,first,rest等我有点疑惑,为什么disjdissoc是不同的,虽然; 他们有完全相同的签名:

(dissoc map) (dissoc map key) (dissoc map key & ks)
(disj set) (disj set key) (disj set key & ks)
Run Code Online (Sandbox Code Playgroud)

和相当类似的语义.为什么这些都不是由同一个功能覆盖?我能看到的唯一一个支持这一点的论点是,map既有(assoc map key val)并且都有(conj map [key val])添加条目,而set只支持(conj set k).

我可以编写一个单行函数来处理这种情况,但是Clojure在很多时候都是如此优雅,以至于每当它不是:)时它真的很刺激我

clojure

6
推荐指数
1
解决办法
1129
查看次数

ActiveRecord 唯一性验证阻止更新

我正在使用 Rails 编写一个网络应用程序,其中一部分包括让用户能够留下评论。我想在模型中进行验证,review以确保一个用户不能对同一项目留下多个评论,所以我写了这样的:

class NoDuplicateReviewValidator < ActiveModel::Validator
  def validate(record)
    dup_reviews = Review.where({user_id: record.user,
                                work_id: record.work})
    unless dup_reviews.length < 1
      record.errors[:duplicate] << "No duplicate reviews!"
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

该验证器具有所需的行为,即它保证用户不能对作品进行两次审查。然而,它有一个不受欢迎的副作用,即用户无法更新他/她留下的现有评论。我正在使用一个非常简单的

def update
  @review.update(review_params)
  respond_with(@work)
end
Run Code Online (Sandbox Code Playgroud)

在评论控制器中。如何更改验证器或更新方法,以便防止重复审查但允许更新?

我对 Rails 和 Web 开发非常陌生,所以我确信我在这里做了一些愚蠢的事情。我没有使用内置unique验证器之一,因为唯一的是user/work对;同一用户对不同作品可以有多个评论,不同用户对同一作品也可以有多个评论。

validation activerecord ruby-on-rails

6
推荐指数
1
解决办法
1234
查看次数

运行时多态性在fortran 2003中

我在Fortran 2003中编写了一些代码,它使用稀疏矩阵执行大量线性代数.我正在尝试利用新标准的一些更抽象的功能,所以我有更简单的程序,没有太多的重复代码.

我有一个过程solver,它接受一个矩阵,一些向量,使用的迭代方法的容差等.我传递一个指向一个调用matvec它的过程的指针; matvec是我们用于矩阵向量乘法的子程序.

问题是,有时候matvec这个过程会在colorlist, color1, color2发送到此过程的常规参数之上引入额外的参数.我可以想到几种处理这个问题的方法.

第一个想法:定义两个不同的抽象接口matvec1,matvec2和两个不同的解算器.这有效,但它意味着复制一些代码,这正是我想要避免的.

另一个想法:保持同样的抽象接口matvec,并进行额外的参数colorlist,color1,color2可选的.这意味着在每个matvec例程中都可以选择它们 - 甚至是那些它们不是真正可选的例程,以及它们甚至根本不用的例程.如果我这样做,我肯定会下地狱.

我可以想到许多其他不太理想的解决方案.我想对此有所了解 - 我确信有一些优雅的方法可以做到,我只是不确定它是什么.

oop polymorphism fortran

5
推荐指数
1
解决办法
874
查看次数

是隐藏的全局坏编程实践?

我正在写一些线性代数代码(在Fortran 2003的,但它会是同样的问题,用Fortran 90或C)需要几个工作向量做计算的,我的想法来处理,这是做一个工作阵列w(:,:),其对于线性代数模块是私有的,即在本讨论中定义的"隐藏全局" ,为什么真正的全局变量是可怕的.

我想这就像在黑板上解决一个大问题一样,对于问题的每个部分,你选择黑板区域来解决它.

根据这个类比,我还可以拥有一堆小白板:定义work_array数据类型并根据需要将它们传递给求解器.(PETSc通过另一个抽象层有效地使用这种方法; a solver是一种数据类型,它包括一些指向所用方法的过程指针以及一些工作向量.)当存在从一个求解器到另一个求解器的嵌套调用时,它得到一个螨虫很复杂,所以我喜欢第一种方式更好.它也不需要那么多误导.

有关哪种方法可以更好地编程实践的想法?

编辑:当我开始使用OpenMP时,我也不认为这将是一个问题,我已经在这个代码的旧版本中完成了.在设置问题后,每个线程只访问其未知数的部分而不访问其他线程的部分.尽管如此,并发问题可能是一般不使用静态变量的好理由.

如果每次调用求解器时都必须为scratch数组动态分配空间,这通常不会产生很多开销吗?

c oop fortran global-variables linear-algebra

5
推荐指数
2
解决办法
306
查看次数

CMake Fortran编译器相关的标志

我正在使用CMake进行中等规模的Fortran项目; 有时我用gfortran构建它,有时用ifort构建它.当我想进行调试构建时,编译器标志是不同的; 我想让CMake自动检查正在使用哪个编译器并相应地设置标志.

看起来这个答案显示了如何为不同的C++编译器做同样的事情.有一个如何使用Fortran检查编译器的示例

if (Fortran_COMPILER_NAME MATCHES "gfortran.*")
Run Code Online (Sandbox Code Playgroud)

但是,这无法调用条件,因为CMake决定使用f95.当然,f95碰巧别名gfortran,但CMake没有检测到.

这样做的正确方法是什么?

fortran cmake

4
推荐指数
1
解决办法
3383
查看次数

在 Common Lisp 中模拟 Clojure 风格的可调用对象

在 Clojure 中,哈希映射和向量实现了invoke,因此它们可以用作函数,例如

(let [dict {:species "Ursus horribilis"
            :ornery :true
            :diet "You"}]
  (dict :diet))

lein> "You"
Run Code Online (Sandbox Code Playgroud)

或者,对于向量,

(let [v [42 613 28]]
  (v 1))

lein> 613
Run Code Online (Sandbox Code Playgroud)

可以通过让它们实现 Clojure 中的可调用对象IFn。我是 Common Lisp 的新手——可调用对象是否可能,如果是的话,实现它会涉及什么?我真的很想能够做这样的事情

(let ((A (make-array (list n n) ...)))
   (loop for i from 0 to n
         for j from 0 to m
      do (setf (A i j) (something i j)))
   A)
Run Code Online (Sandbox Code Playgroud)

而不是让代码乱七八糟aref。同样,如果您可以以相同的方式访问其他数据结构的条目,例如字典,那将会很酷。

我已经查看了Lisp/Scheme 中函数对象的wiki 条目,似乎拥有一个单独的函数命名空间会使 CL 的问题复杂化,而在 Scheme 中,您可以使用闭包来做到这一点。

clojure common-lisp lisp-2 callable-object

2
推荐指数
1
解决办法
442
查看次数

mpi改变它不应该的变量

我有一些Fortran代码,我正在与MPI并行化,这正在做着真正奇怪的事情.首先,我有一个变量nstartg,我从老板流程向所有工人广播:

call mpi_bcast(nstartg,1,mpi_integer,0,mpi_comm_world,ierr)
Run Code Online (Sandbox Code Playgroud)

该程序中的变量nstartg永远不会再次更改.后来,我让老板进程向工人发送eproc一个数组元素edge:

if (me==0) then
    do n=1,ntasks-1
        (determine the starting point estart and the number eproc
         of values to send)
        call mpi_send(edge(estart),eproc,mpi_integer,n,n,mpi_comm_world,ierr)
    enddo
endif
Run Code Online (Sandbox Code Playgroud)

如果me非零,则匹配的receive语句.(为了便于阅读,我遗漏了一些其他代码;我有一个很好的理由不使用scatterv.)

事情变得奇怪:变量nstartg被改变n而不是保持其实际值.例如,在进程1上,在mpi_recv之后nstartg = 1,在进程2上它等于2,依此类推.此外,如果我将上面的代码更改为

call mpi_send(edge(estart),eproc,mpi_integer,n,n+1234567,mpi_comm_world,ierr)
Run Code Online (Sandbox Code Playgroud)

并在匹配调用mpi_recv时相应地更改标记,然后在进程1,nstartg = 1234568; 在过程2,nstartg = 1234569等

到底是怎么回事?我改变的是mpi_send/recv用于识别消息的标签; 如果标签是唯一的,那么消息不会混淆,这不应该改变任何东西,但它改变了一个完全不相关的变量.

在老板的过程中,nstartg没有改变,所以我可以通过再次播放来解决这个问题,但这不是一个真正的解决方案.最后,我应该提一下,使用电栅编译和运行此代码并没有发现任何缓冲区溢出,也没有--fbounds-check向我抛出任何东西.

fortran mpi fortran90

1
推荐指数
1
解决办法
475
查看次数

我可以假设 Fortran 预处理器适用于大多数系统吗?

我正在尝试在 Fortran 中模拟 C 断言,以便强制执行所有过程的前置条件和后置条件。通过这种方式,我可以向用户提供有关运行时错误的更详细的信息,而不是我可以合理预期维护的信息。

为了实现这一点,我使用了预处理器指令__FILE____LINE__,并定义了一个assert扩展为 Fortran 子例程调用的宏。我没有尝试在这里描述它,而是创建了一个git 存储库,其中包含一些示例代码。如果你用它来构建它

make test
./test
Run Code Online (Sandbox Code Playgroud)

该函数挂起,因为您调用的函数需要正参数和负参数。但是,如果您使用

make test DEBUG=1
./test
Run Code Online (Sandbox Code Playgroud)

错误被断言捕获。

这适用于 gfortran 和 Intel Fortran 编译器。我无法访问其他 Fortran 编译器。如果文件扩展名是 ,我可以合理地期望其他编译器进行必要的源预处理吗.F90?或者我应该依靠旗帜-cpp?最便携的方法是什么?我到底应该这样做吗?

preprocessor fortran

1
推荐指数
1
解决办法
325
查看次数